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(树状数组区间更新单点求值&暴力)
原文:http://www.cnblogs.com/wgwyanfs/p/6752462.html