hdu6089 Rikka with Terrorist

标程:

 1 #include<bits/stdc++.h>
 2 #define mid ((l+r)>>1)
 3 using namespace std;
 4 int read()
 5 {
 6    int x=0,f=1;char ch=getchar();
 7    while (ch<'0'||ch>'9') {if (ch=='-') f=-1;ch=getchar();}
 8    while (ch>='0'&&ch<='9') x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
 9    return x*f;
10 }
11 const int N=100005;
12 typedef long long ll;
13 int n,m,K,Q,T_Max[N<<2],tot,Max;
14 ll ans[N],T_sum[N<<2],T_suml[N<<2];
15 struct node{int x,y,id,ty;node(){} node(int a,int b,int c,int d){x=a;y=b;id=c;ty=d;}}a[N*2],dg[N],q[N];
16 bool cmp(const node &A,const node &B) {return A.x<B.x||A.x==B.x&&A.y<B.y||A.x==B.x&&A.y==B.y&&A.ty<B.ty;}//排序时||不要写成&&! 
17 ll qry_sum(int k,int l,int r,int L,int R,int &mx)//表示当前区间的右边下界为mx时的折线下面积 
18 {
19     if (L<=l&&r<=R)
20     {
21         if (mx>=T_Max[k]) return (ll)mx*(r-l+1);   
22         if (l==r) return mx=T_Max[k]; 
23         int tt=T_Max[k<<1|1]; ll res=0;
24         if (mx>=tt)
25         {
26            res+=(ll)mx*(r-mid);//mx会被修改,注意统计顺序! 
27             res+=qry_sum(k<<1,l,mid,L,R,mx);
28         }else {
29             res+=T_suml[k];
30             res+=qry_sum(k<<1|1,mid+1,r,L,R,mx); 
31         }
32         mx=T_Max[k]; return res;
33     }
34     ll s=0;
35     if (R>mid) s+=qry_sum(k<<1|1,mid+1,r,L,R,mx);//先走右边,更新下界 
36     if (L<=mid) s+=qry_sum(k<<1,l,mid,L,R,mx);
37     return s;
38 }
39 void ins(int k,int l,int r,int x,int y)
40 {
41     if (l==r)
42     {
43         if (y>T_Max[k]) T_Max[k]=T_sum[k]=y;
44         return; 
45     }
46     if (x<=mid) ins(k<<1,l,mid,x,y);else ins(k<<1|1,mid+1,r,x,y);
47     int tt=T_Max[k<<1|1];
48     T_suml[k]=qry_sum(k<<1,l,mid,l,mid,tt);//注意如果直接传入T_Max[k<<1|1]的话,在&下会被修改。 
49     T_Max[k]=max(T_Max[k<<1],T_Max[k<<1|1]); 
50     T_sum[k]=T_suml[k]+T_sum[k<<1|1];
51 }
52 void work()
53 {
54     tot=0;
55     for (int i=1;i<=K;i++) a[++tot]=node(dg[i].x,dg[i].y,i,0);
56     for (int i=1;i<=Q;i++) a[++tot]=node(q[i].x,q[i].y,i,1);
57     sort(a+1,a+tot+1,cmp);
58     for (int i=1;i<=tot;i++)
59     {
60         if (!a[i].ty) ins(1,1,m,a[i].y,a[i].x);
61         else {
62             Max=0;ans[a[i].id]+=qry_sum(1,1,m,1,a[i].y,Max);
63             Max=0;ans[a[i].id]-=qry_sum(1,1,m,a[i].y,a[i].y,Max);//减去重复的一条同行/同列轴 
64         }
65     }
66 } 
67 int main()
68 {
69     int T=read();
70     while (T--)
71     {
72        n=read();m=read();K=read();Q=read();
73        for (int i=1;i<=K;i++) dg[i].x=read(),dg[i].y=read();
74        for (int i=1;i<=Q;i++) q[i].x=read(),q[i].y=read(),ans[i]=0;//组测清零 
75         for (int i=0;i<4;i++)
76         {
77             work();
78             for (int i=1;i<=(m<<2);i++) T_sum[i]=T_suml[i]=T_Max[i]=0; 
79             for (int j=1;j<=K;j++) dg[j].x=n-dg[j].x+1,swap(dg[j].x,dg[j].y);//90度旋转坐标 
80             for (int j=1;j<=Q;j++) q[j].x=n-q[j].x+1,swap(q[j].x,q[j].y); 
81             swap(n,m);
82         }
83         for (int i=1;i<=Q;i++) printf("%lld\n",(ll)n*m-ans[i]);
84     } 
85    return 0;
86 }

猜你喜欢

转载自www.cnblogs.com/Scx117/p/9115327.html