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 */