2019icpc南京网络赛 A The beautiful values of the palace(离线+树状数组)

题意:

(假设所有的点对应的值已经求出)给你一个1e6*1e6的矩阵,有m<=1e5个点有值,其余都为0

q<=1e5个询问,求子矩阵的权值和

思路:

根据二维差分,对于询问左下角(x1,y1),右上角(x2,y2)

该询问答案为a[x2][y2]-a[x1-1][y2]-a[x2][y1-1]+a[x1-1][y1-1]

其中a为二维前缀和

那么我们把询问拆成四个前缀和,和m个点一起离线,树状数组更新答案即可

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<string>
#include<stack>
#include<queue>
#include<deque>
#include<set>
#include<vector>
#include<map>
    
#define fst first
#define sc second
#define pb push_back
#define mem(a,b) memset(a,b,sizeof(a))
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
#define lc root<<1
#define rc root<<1|1
#define lowbit(x) ((x)&(-x)) 

using namespace std;

typedef double db;
typedef long double ldb;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> PI;
typedef pair<ll,ll> PLL;

const db eps = 1e-6;
const int mod = 1e9+7;
const int maxn = 2e6+100;
const int maxm = 2e6+100;
const int inf = 0x3f3f3f3f;
const db pi = acos(-1.0);

struct node{
    ll lx;//U1 Q0
    ll id,x,y,v;
    node(){}
    node(ll lx, ll id, ll x, ll y, ll v):lx(lx),id(id),x(x),y(y),v(v){
        printf("**%lld %lld %lld %lld %lld\n",lx,id,x,y,v);
    }
}Q[maxn];
bool cmp(node a, node b){
    if(a.x==b.x&&a.y==b.y){
        return a.lx>b.lx;
    }
    if(a.x==b.x)return a.y<b.y;
    return a.x<b.x;
}
ll tree[maxn];
ll ans[maxn];
ll n, m, q;
void add(int x, ll c){for(int i=x;i<=n;i+=lowbit(i))tree[i]+=c;}
ll sum(int x){
    ll ans = 0;
    for(int i = x; i; i-=lowbit(i))ans+=tree[i];
    return ans;
}
int main() {
    int t;
    scanf("%d", &t);
    while(t--){
        scanf("%lld %lld %lld", &n, &m, &q);
        int tot = 0;
        for(int i = 0; i < maxn; i++){
            tree[i]=ans[i]=0;
        }
        for(int i = 1; i <= m; i++){
            ll x, y;
            ll res;
            scanf("%lld %lld", &x, &y);
            x=x-n/2-1;y=y-n/2-1;
            ll T = max(abs(x),abs(y));
            if(x>=y)res=1ll*n*n-4*T*T-2*T-x-y;
            else    res=1ll*n*n-4*T*T+2*T+x+y;
            ll c=0;
            while(res){c+=res%10;res/=10;}
            Q[++tot]=node(1,i,x+n/2+1,y+n/2+1,c);
        }
        for(int i = 1; i <= q; i++){
            ll x1,y1,x2,y2;
            scanf("%lld %lld %lld %lld",&x1, &y1, &x2, &y2);
            Q[++tot]=node(0,i,x2,y2,1);
            Q[++tot]=node(0,i,x1-1,y1-1,1);
            Q[++tot]=node(0,i,x1-1,y2,-1);
            Q[++tot]=node(0,i,x2,y1-1,-1);
        }
        sort(Q+1,Q+1+tot,cmp);
        for(int i = 1; i <= tot; i++){
            if(Q[i].x<1||Q[i].y<1)continue;
            if(Q[i].lx==1)add(Q[i].y,Q[i].v);
            else ans[Q[i].id]+=1ll*Q[i].v*sum(Q[i].y);
        }
        for(int i = 1; i <= q; i++){
            printf("%lld\n",ans[i]);
        }
    }
    return 0;
}
/*
22
3 4 4
1 1
2 2
3 3
2 3
1 1 1 1
2 2 3 2
1 1 2 2 
1 1 2 3
 */

 

posted @ 2019-09-05 14:05  wrjlinkkkkkk  阅读(249)  评论(0编辑  收藏  举报