zoukankan      html  css  js  c++  java
  • JZOJ 7339.改试卷

    $ ext

    又忘了线段树分治!! 显然维护一个上凸包 发现加点和删点可以变成限制存在时间 然后把点放在线段树上,线段树下标表示时间 加点时先把点按横坐标排序,然后就可以单调队列维护每个线段树节点的上凸包 询问再按斜率排序,这样可以弹点而不需要二分了 (O(n log n))

    $ ext

    #include <cstdio>
    #include <iostream>
    #include <vector>
    #include <algorithm>
    #define re register
    #define ls (p << 1)
    #define rs (ls | 1)
    using namespace std;
    typedef long long LL;
    
    const int N = 1e6 + 5;
    const LL INF = 0x3f3f3f3f3f3f3f3f;
    int n, totp, totq, bz[N];
    LL ans[N];
    
    struct point{int x, y, st, ed;}P[N];
    struct que{int a, b, ti, id;}Q[N];
    inline bool cmpx(point u, point v){return u.x < v.x ? 1 : (u.x == v.x ? u.y > v.y : 0);}
    inline bool cmp(que u, que v){return -1.0 * u.a / u.b < -1.0 * v.a / v.b;}
    inline double slope(int u, int v)
    {
    	if (P[u].x == P[v].x) return -INF;
    	return 1.0 * (P[u].y - P[v].y) / (P[u].x - P[v].x);
    }
    
    inline void read(int &x)
    {
    	x = 0; char ch = getchar();
    	for(; !isdigit(ch); ch = getchar());
    	for(; isdigit(ch); x = (x<<3) + (x<<1) + (ch^48), ch = getchar());
    }
    
    vector<int> T[N * 4];
    void update(int p, int l, int r, int tl, int tr, int x)
    {
    	if (tl <= l && r <= tr)
    	{
    		int sz = T[p].size();
    		while (sz > 1 && slope(T[p][sz - 1], T[p][sz - 2]) < slope(T[p][sz - 1], x))
    			T[p].pop_back(), sz = T[p].size();
    		T[p].push_back(x);
    		return;
    	}
    	int mid = (l + r) >> 1;
    	if (tl <= mid) update(ls, l, mid, tl, tr, x);
    	if (tr > mid) update(rs, mid + 1, r, tl, tr, x);
    }
    LL query(int p, int l, int r, int x)
    {
    	LL res = 0;
    	int sz = T[p].size();
    	while (sz > 1 && slope(T[p][sz - 1], T[p][sz - 2]) < -1.0 * Q[x].a / Q[x].b)
    		T[p].pop_back(), sz = T[p].size();
    	if (sz) res = 1LL * Q[x].a * P[T[p][sz - 1]].x + 1LL * Q[x].b * P[T[p][sz - 1]].y;
    	if (l == r) return res;
    	int mid = (l + r) >> 1;
    	if (Q[x].ti <= mid) return max(res, query(ls, l, mid, x));
    	return max(res, query(rs, mid + 1, r, x));
    }
    
    int main()
    {
    	freopen("paper.in", "r", stdin), freopen("paper.out", "w", stdout);
    	read(n);
    	for(re int i = 1, ty; i <= n; i++)
    	{
    		read(ty);
    		if (ty == 3) ++totq, read(Q[totq].a), read(Q[totq].b), Q[totq].ti = i, Q[totq].id = totq;
    		else if (ty == 1)
    			bz[i] = ++totp, read(P[totp].x), read(P[totp].y), P[totp].st = i, P[totp].ed = n;
    		else read(ty), P[bz[ty]].ed = i;
    	}
    	sort(P + 1, P + totp + 1, cmpx), sort(Q + 1, Q + totq + 1, cmp);
    	for(re int i = 1; i <= totp; i++) update(1, 1, n, P[i].st, P[i].ed, i);
    	for(re int i = 1; i <= totq; i++) 
    	if (!Q[i].ti) ans[Q[i].id] = 0; else ans[Q[i].id] = query(1, 1, n, i);
    	for(re int i = 1; i <= totq; i++) printf("%lld
    ", ans[i]);
    }
    
  • 相关阅读:
    A.02.01—功能定义—一般定义
    A.02.00—功能定义与唤醒—起始
    A.01.12—模块的输出—通讯(CAN&LIN)
    A.01.11—模块的输出—输出复用和可配
    A.01.10—模块的输出—PWM高端输出
    A.01.09—模块的输出—PWM低端输出
    redis命令
    memcached命令
    kafka命令
    nginx命令
  • 原文地址:https://www.cnblogs.com/leiyuanze/p/15512901.html
Copyright © 2011-2022 走看看