2014多校9 1011
http://acm.hdu.edu.cn/showproblem.php?pid=4970
Killing MonstersTime Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others) Problem Description Kingdom Rush is a popular TD game, in which you should build some The path of monsters is a straight line, and there A witch helps your enemies and makes Now that Input The input contains multiple test cases. The first line of each case is an integer N (0 < N <= 100000), The input is terminated by N = 0. Output Output one line containing the number of surviving monsters. Sample Input 5 Sample Output 3 Hint In the sample, three monsters with origin HP 5, 7 and 9 will survive. Source 2014 Multi-University Training Contest 9 Recommend hujie | We have carefully selected several similar problems for you: 4970 4969 4968 4967 4966 |
题意:塔防,怪走一条直线,可以分成1~n共n格。给出m个塔的攻击范围(Li~Ri),攻击力Di,怪物走过这格会减少Di血量。给出k个怪物的血量、出生格,求有多少个怪物可以走到终点。
题解:差分数列搞。
粗略一看,是区间加减、区间求和,线段树!会超时,怕了。
再一看,是区间加减完再区间求和,而且求和还是有限制的,就求i~n的和。
用差分数列可以轻松区间加减,差分数列就是b[i]=a[i]-a[i-1],区间[i,j]加D就是b[i]=b[i]+d , b[j+1]=b[j+1]-d。
但是怎么求和呢?我们把和写出来观察一下:
an = bn
an-1 + an =2an - bn
an-2 + an-1 + an = 3an - 2bn - bn-1
看起来很好算的样子!
于是这样就能算(其中an就是an ,其中c[i]就是ai加到an的和):
1 ll one=an,many=an; 2 for(i=n;i>0;i--){ 3 c[i]=many; 4 one-=b[i]; 5 many+=one; 6 }
这样就轻松算啦。
我一开始想到差分数列,不过没仔细想怎么求和,然后就去线段树了,逗乐。后来才发现居然这么好求。
全代码:
1 //#pragma comment(linker, "/STACK:102400000,102400000") 2 #include<cstdio> 3 #include<cmath> 4 #include<iostream> 5 #include<cstring> 6 #include<algorithm> 7 #include<cmath> 8 #include<map> 9 #include<set> 10 #include<stack> 11 #include<queue> 12 using namespace std; 13 #define ll long long 14 #define usll unsigned ll 15 #define mz(array) memset(array, 0, sizeof(array)) 16 #define minf(array) memset(array, 0x3f, sizeof(array)) 17 #define REP(i,n) for(i=0;i<(n);i++) 18 #define FOR(i,x,n) for(i=(x);i<=(n);i++) 19 #define RD(x) scanf("%d",&x) 20 #define RD2(x,y) scanf("%d%d",&x,&y) 21 #define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z) 22 #define WN(x) prllf("%d\n",x); 23 #define RE freopen("D.in","r",stdin) 24 #define WE freopen("1biao.out","w",stdout) 25 #define mp make_pair 26 #define pb push_back 27 28 const int maxn=111111; 29 30 int n,m,k; 31 int l[maxn],r[maxn],d[maxn]; 32 int x[maxn]; 33 ll h[maxn]; 34 ll b[maxn]; 35 ll c[maxn]; 36 ll an=0; 37 38 void Update(int L, int R, int x){ 39 b[L]+=x; 40 b[R+1]-=x; 41 if(R==n)an+=x; 42 } 43 44 int main(){ 45 int i; 46 while(scanf("%d",&n)!=EOF){ 47 if(n==0)break; 48 scanf("%d",&m); 49 mz(b);mz(c);an=0; 50 REP(i,m) { 51 scanf("%d%d%d",&l[i],&r[i],&d[i]); 52 Update(l[i],r[i],d[i]); 53 } 54 ll one=an,many=an; 55 for(i=n;i>0;i--){ 56 c[i]=many; 57 one-=b[i]; 58 many+=one; 59 } 60 //for(i=1;i<=n;i++)printf("%I64d\n",c[i]); 61 int ans=0; 62 //for(i=1;i<=n;i++)printf("(%d,%d),%d\n",i,n,Query(i,n,1,n,1)); 63 scanf("%d",&k); 64 REP(i,k) { 65 scanf("%I64d%d",&h[i],&x[i]); 66 if(c[x[i]]< h[i])ans++; 67 } 68 printf("%d\n",ans); 69 } 70 return 0; 71 }
hdu4970 Killing Monsters (差分数列),布布扣,bubuko.com