标签:lowbit 线段树 man ref time 最大 unit acm about
2 3 7 2 Attack 1 2 Query 2 Attack 2 3 Query 2 Attack 1 3 Query 1 Query 3 9 7 3 Attack 5 5 Attack 4 6 Attack 3 7 Attack 2 8 Attack 1 9 Query 5 Query 3
Case 1: 0 1 0 1 Case 2: 3 2
攻击[L,R]。或询问某单位墙被成功攻击的次数。
和查询一个点值。这个有两种写法。然后一个墙被成功攻击的次数就等于总攻击次数-被抵挡的攻击次数。关于被抵挡的攻击次数的算法就近乎暴力了。
。反正分析时间复杂度怎么都会超的。
可是没出那样的数据而已。
#include<algorithm> #include<iostream> #include<string.h> #include<stdio.h> using namespace std; const int INF=0x3f3f3f3f; const int maxn=100010; typedef long long ll; int C[maxn],n,attack[maxn][2],head[maxn],num[maxn]; int lowbit(int x) { return x&-x; } void update(int x,int d) { for(int i=x;i>0;i-=lowbit(i)) C[i]+=d; } int getsum(int x) { int i,sum=0; for(i=x;i<=n;i+=lowbit(i)) sum+=C[i]; return sum; } int main() { int t,q,tm,i,j,ct,cas=1,a,b; char cmd[20]; scanf("%d",&t); while(t--) { scanf("%d%d%d",&n,&q,&tm); for(i=1;i<=n;i++) C[i]=num[i]=0,head[i]=0; ct=0; printf("Case %d:\n",cas++); while(q--) { scanf("%s%d",cmd,&a); if(cmd[0]==‘A‘) { scanf("%d",&b); attack[ct][0]=a; attack[ct][1]=b; ct++; update(b,1); update(a-1,-1);//和线段树相似.加个lazy。等要算的时候在顺着父亲累加上去。 } else { for(j=head[a];j<ct;j++) if(attack[j][0]<=a&&attack[j][1]>=a) num[a]++,head[a]=j+tm,j+=tm-1; printf("%d\n",getsum(a)-num[a]); } } } return 0; }
#include<algorithm> #include<iostream> #include<string.h> #include<stdio.h> using namespace std; const int INF=0x3f3f3f3f; const int maxn=100010; typedef long long ll; int C[maxn],n,attack[maxn][2],head[maxn],num[maxn]; int lowbit(int x) { return x&-x; } void update(int x,int d) { for(int i=x;i<=n;i+=lowbit(i)) C[i]+=d; } int getsum(int x) { int i,sum=0; for(i=x;i>0;i-=lowbit(i)) sum+=C[i]; return sum; } int main() { int t,q,tm,i,j,ct,cas=1,a,b; char cmd[20]; scanf("%d",&t); while(t--) { scanf("%d%d%d",&n,&q,&tm); for(i=1;i<=n;i++) C[i]=num[i]=head[i]=0; ct=0; printf("Case %d:\n",cas++); while(q--) { scanf("%s%d",cmd,&a); if(cmd[0]==‘A‘) { scanf("%d",&b); attack[ct][0]=a; attack[ct][1]=b; ct++; update(a,1);//用打标记的方法。前缀和就是当前点的值。 update(b+1,-1); } else { for(j=head[a];j<ct;j++) if(attack[j][0]<=a&&attack[j][1]>=a) num[a]++,head[a]=j+tm,j+=tm-1;//由于j在for循环还要加1所以仅仅能加tm-1 printf("%d\n",getsum(a)-num[a]); } } } return 0; }
hdu 4031 Attack(树状数组区间更新单点求值&暴力)
标签:lowbit 线段树 man ref time 最大 unit acm about
原文地址:http://www.cnblogs.com/wgwyanfs/p/6752462.html