4822: [Cqoi2017]老C的任务

来源:互联网 发布:linux 安全扫描工具 编辑:程序博客网 时间:2024/05/22 01:53

每次统计一个矩形内的点权和

拆成四个小矩形作差分

扫描线+树状数组即可

#include<iostream>#include<cstdio>#include<vector>#include<algorithm>#include<cstring>using namespace std; const int maxn = 1E5 + 10;const int Max = ~0U>>1;const int Min = -(1LL << 31LL);typedef long long LL; struct Query{    int y,Num,typ; Query(){}    Query(int y,int Num,int typ):        y(y),Num(Num),typ(typ){}}; int n,m,cx,cy,tx,ty,ax[maxn],ay[maxn],px[maxn],py[maxn],p[maxn];LL Ans[maxn],sum[maxn]; vector <Query> Q[maxn];vector <pair<int,int> > P[maxn]; inline int getint(){    char ch = getchar(); int ret = 0,a = 1;    while (ch < '0' || '9' < ch)    {        if (ch == '-') a = -1;        ch = getchar();    }    while ('0' <= ch && ch <= '9')        ret = ret * 10 + ch - '0',ch = getchar();    return ret * a;} inline void Add(int x,int y,int Num,int typ){    int nx = lower_bound(ax + 1,ax + cx + 1,x) - ax;    int ny = lower_bound(ay + 1,ay + cy + 1,y) - ay;    if (ax[nx] > x) --nx; if (ay[ny] > y) --ny;    Q[nx].push_back(Query(ny,Num,typ));} void Pre_Work(){    for (int i = 1; i <= n; i++)    {        ax[i] = px[i] = getint();        ay[i] = py[i] = getint();        p[i] = getint();    }    cx = 1; ax[++tx] = Min; ax[++tx] = Max;    cy = 1; ay[++ty] = Min; ay[++ty] = Max;    sort(ax + 1,ax + tx + 1);    for (int i = 2; i <= tx; i++)        if (ax[i] != ax[i - 1]) ax[++cx] = ax[i];    sort(ay + 1,ay + ty + 1);    for (int i = 2; i <= ty; i++)        if (ay[i] != ay[i - 1]) ay[++cy] = ay[i];    for (int i = 1; i <= n; i++)    {        px[i] = lower_bound(ax + 1,ax + cx + 1,px[i]) - ax;        py[i] = lower_bound(ay + 1,ay + cy + 1,py[i]) - ay;        P[px[i]].push_back(make_pair(py[i],p[i]));    }    for (int i = 1; i <= m; i++)    {        int xa,ya,xb,yb;        xa = getint(); ya = getint();        xb = getint(); yb = getint(); Add(xb,yb,i,1);        if (xa > Min) Add(xa - 1,yb,i,-1);        if (ya > Min) Add(xb,ya - 1,i,-1);        if (xa > Min && ya > Min) Add(xa - 1,ya - 1,i,1);    }} int main(){    #ifdef DMC        freopen("DMC.txt","r",stdin);    #endif         tx = ty = n = getint();    m = getint(); Pre_Work();    for (int i = 1; i <= cx; i++)    {        for (int j = 0; j < P[i].size(); j++)            for (int k = P[i][j].first; k <= cy; k += k&-k)                sum[k] += 1LL * P[i][j].second;        for (int j = 0; j < Q[i].size(); j++)        {            Query now = Q[i][j]; LL tot = 0;            for (int k = now.y; k > 0; k -= k&-k) tot += sum[k];            Ans[now.Num] += 1LL * now.typ * tot;        }    }    for (int i = 1; i <= m; i++) printf("%lld\n",Ans[i]);    return 0;}

0 0
原创粉丝点击