NYOJ 士兵杀敌(1~5)

士兵杀敌(1): http://acm.nyist.net/JudgeOnline/problem.php?pid=108

分析:前缀和

 1
 2 #include <bits/stdc++.h>
 3
 4 using namespace std;
 5
 6 int a[1000005];
 7 int sum[1000005];
 8
 9 int main()
10 {
11     int n,m;
12     scanf("%d%d",&n,&m);
13
14     sum[0] = 0;
15     for(int i=1;i<=n;i++) {
16         scanf("%d",&a[i]);
17         sum[i] = sum[i-1] + a[i];
18     }
19
20     while(m--) {
21         int m,n;
22         scanf("%d%d",&m,&n);
23         if(m>n)
24             swap(m,n);
25         printf("%d\n",sum[n]-sum[m-1]);
26
27     }
28
29     return 0;
30 }
31         

士兵杀敌(2):http://acm.nyist.net/JudgeOnline/problem.php?pid=116

分析:树状数组(单点更新,区间求和)

 1
 2 #include <bits/stdc++.h>
 3
 4 using namespace std;
 5
 6 const int maxn = 1000000+5;
 7
 8 int C[maxn];
 9 int n,m;
10
11
12 int lowbit(int x) {
13     return x&-x;
14 }
15
16 //A[1] + A[2] + ... + A[x]
17 int sum(int x) {
18     int ret = 0;
19     while(x>0) {
20         ret +=C[x];
21         x-=lowbit(x);
22     }
23     return ret;
24 }
25
26 //A[x] +=d;
27 void add(int x,int d) {
28     while(x<=n) {
29         C[x] +=d;
30         x+=lowbit(x);
31     }
32 }
33
34 int main()
35 {
36     scanf("%d%d",&n,&m);
37     for(int i=1;i<=n;i++) {
38         int x;
39         scanf("%d",&x);
40         add(i,x);
41     }
42
43     char cmd[10];
44     for(int i=0;i<m;i++) {
45         scanf("%s",cmd);
46         if(cmd[0]==‘A‘)
47         {
48             int x,d;
49             scanf("%d%d",&x,&d);
50             add(x,d);
51         }
52         else {
53             int u,v;
54             scanf("%d%d",&u,&v);
55             printf("%d\n",sum(v)-sum(u-1));
56         }
57     }
58
59     return 0;
60 }
61         

士兵杀敌(3):http://acm.nyist.net/JudgeOnline/problem.php?pid=119

分析:RMQ

 1
 2 #include <bits/stdc++.h>
 3
 4 using namespace std;
 5
 6 const int maxn = 100005;
 7
 8 struct RMQ {
 9
10     int dmin[maxn][20];
11     int dmax[maxn][20];
12
13     void RMQ_init(const vector<int>& A) {
14         int n = A.size();
15         for(int i=0;i<n;i++)
16         {
17             dmin[i][0] = A[i];
18             dmax[i][0] = A[i];
19         }
20
21         for(int j=1;(1<<j)<=n;j++) {
22             for(int i=0;i+(1<<j)-1<n;i++) {
23                 dmin[i][j] = min(dmin[i][j-1],dmin[i+(1<<(j-1))][j-1]);
24                 dmax[i][j] = max(dmax[i][j-1],dmax[i+(1<<(j-1))][j-1]);
25             }
26         }
27     }
28
29     int RMQ_min(int L,int R) {
30         int k = 0;
31         while((1<<(k+1))<=R-L+1)
32             k++;
33         return min(dmin[L][k],dmin[R-(1<<k)+1][k]);
34     }
35
36     int RMQ_max(int L,int R) {
37         int k = 0;
38         while((1<<(k+1))<=R-L+1)
39             k++;
40         int ans = max(dmax[L][k],dmax[R-(1<<k)+1][k]);
41         return ans;
42     }
43
44
45 }sol;
46
47 int main()
48 {
49     int n,m;
50     scanf("%d%d",&n,&m);
51     vector<int> v;
52     for(int i=0;i<n;i++) {
53         int x;
54         scanf("%d",&x);
55         v.push_back(x);
56     }
57     sol.RMQ_init(v);
58
59     for(int i=0;i<m;i++) {
60         int l,r;
61         scanf("%d%d",&l,&r);
62         l--;r--;
63         printf("%d\n",sol.RMQ_max(l,r)-sol.RMQ_min(l,r));
64     }
65
66     return 0;
67 }
68         

士兵杀敌(4):http://acm.nyist.net/JudgeOnline/problem.php?pid=123

分析:区间更新,单点查询;

线段树超时,要优化线段树,线段树这么高级,我可不会改板子啊 (*^__^*)

解法:利用树状数组的逆过程!!!

add的时候,就把路上的C[x] 全都加上;(add(qR,v);add(qL-1,v))

询问的时候,往右上走,看看总共有多少给这个点产生了影响;

 1
 2 #include <bits/stdc++.h>
 3
 4 using namespace std;
 5
 6 const int maxn = 1000000+5;
 7 int C[maxn];
 8 int m,t;
 9 int lowbit(int x)
10 {
11     return x&-x;
12 }
13
14 void add(int star,int num) {
15     while(star>0) {
16         C[star]+=num;
17         star-=lowbit(star);
18     }
19 }
20
21 int sum(int star) {
22     int sum = 0;
23     while(star<=m) {
24         sum+=C[star];
25         star+=lowbit(star);
26     }
27     return sum;
28 }
29
30 int main()
31 {
32     scanf("%d%d",&t,&m);
33     while(t--) {
34         char cmd[10];
35         scanf("%s",cmd);
36         if(cmd[0]==‘A‘) {
37             int u,v,c;
38             scanf("%d%d%d",&u,&v,&c);
39             add(v,c);
40             add(u-1,-c);
41         }
42         else {
43             int pos;
44             scanf("%d",&pos);
45             printf("%d\n",sum(pos));
46         }
47     }
48
49     return 0;
50 }
51         

士兵杀敌(5):http://acm.nyist.net/JudgeOnline/problem.php?pid=228

分析:区间更新,线段查询;

线段树又超时了 (ノへ ̄、)

解法:巧用数组,记录下来每个区间的更新的起点,和结束的起点,然后累加计算出正确数组;

再求一个前缀和;

  1 /*
  2 #include <bits/stdc++.h>
  3
  4 using namespace std;
  5
  6 const int maxnode = 1000001<<2;
  7 int _min,_max,_sum;
  8 int qL,qR,v;
  9
 10 struct IntervalTree
 11 {
 12     int sumv[maxnode], minv[maxnode], maxv[maxnode], addv[maxnode];
 13     void maintain(int o, int L, int R)
 14     {
 15         int lc = o*2, rc = o*2+1;
 16         sumv[o] = minv[o] = maxv[o] = 0;
 17         if(R > L)
 18         {
 19             sumv[o] = sumv[lc] + sumv[rc];
 20             minv[o] = min(minv[lc], minv[rc]);
 21             maxv[o] = max(maxv[lc], maxv[rc]);
 22         }
 23         if(addv[o])
 24         {
 25             minv[o] += addv[o];
 26             maxv[o] += addv[o];
 27             sumv[o] += addv[o] * (R-L+1);
 28         }
 29     }
 30
 31     void update(int o, int L, int R)
 32     {
 33         int lc = o*2, rc = o*2+1;
 34         if(qL <= L && qR >= R)
 35         {
 36             addv[o] += v;
 37         }
 38         else
 39         {
 40             int M = L + (R-L)/2;
 41             if(qL <= M) update(lc, L, M);
 42             if(qR > M) update(rc, M+1, R);
 43         }
 44         maintain(o, L, R);
 45     }
 46
 47     void query(int o, int L, int R, int add)
 48     {
 49         if(qL <= L && qR >= R)
 50         {
 51             _sum += (sumv[o] + add * (R-L+1))%10003;
 52             _min = min(_min, minv[o] + add);
 53             _max = max(_max, maxv[o] + add);
 54         }
 55         else
 56         {
 57             int M = L + (R-L)/2;
 58             if(qL <= M) query(o*2, L, M, add + addv[o]);
 59             if(qR > M) query(o*2+1, M+1, R, add + addv[o]);
 60         }
 61     }
 62
 63 }tree;
 64
 65 int main()
 66 {
 67     int n,c,q;
 68     scanf("%d%d%d",&n,&c,&q);
 69     while(c--) {
 70         scanf("%d%d%d",&qL,&qR,&v);
 71         tree.update(1,1,n);
 72     }
 73
 74     while(q--) {
 75         _sum = 0;
 76         scanf("%d%d",&qL,&qR);
 77         tree.query(1,1,n,0);
 78         printf("%d\n",_sum);
 79     }
 80
 81     return 0;
 82 }
 83 */
 84
 85 #include <bits/stdc++.h>
 86
 87 using namespace std;
 88
 89 const int maxn = 1000005;
 90 int num[maxn];
 91
 92 int main()
 93 {
 94     int n,c,q;
 95     memset(num,0,sizeof(num));
 96     scanf("%d%d%d",&n,&c,&q);
 97     for(int i=0;i<c;i++) {
 98         int l,r,v;
 99         scanf("%d%d%d",&l,&r,&v);
100         num[l]+=v;
101         num[r+1]-=v;
102     }
103
104     for(int i=1;i<=n;i++) {
105         num[i]+=num[i-1];
106     }
107
108     for(int i=1;i<=n;i++) {
109         num[i]=(num[i]+num[i-1])%10003;
110     }
111     while(q--) {
112         int l,r;
113         scanf("%d%d",&l,&r);
114         printf("%d\n",(num[r]-num[l-1]+10003)%10003);
115     }
116
117     return 0;
118 }

时间: 2025-01-02 06:05:30

NYOJ 士兵杀敌(1~5)的相关文章

NYOJ 士兵杀敌(二)

士兵杀敌(二) 时间限制:1000 ms  |  内存限制:65535 KB 难度:5 描述 南将军手下有N个士兵,分别编号1到N,这些士兵的杀敌数都是已知的. 小工是南将军手下的军师,南将军经常想知道第m号到第n号士兵的总杀敌数,请你帮助小工来回答南将军吧. 南将军的某次询问之后士兵i可能又杀敌q人,之后南将军再询问的时候,需要考虑到新增的杀敌数. 输入 只有一组测试数据第一行是两个整数N,M,其中N表示士兵的个数(1<N<1000000),M表示指令的条数.(1<M<10000

NYOJ 士兵杀敌(三)

描述 南将军统率着N个士兵,士兵分别编号为1~N,南将军经常爱拿某一段编号内杀敌数最高的人与杀敌数最低的人进行比较,计算出两个人的杀敌数差值,用这种方法一方面能鼓舞杀敌数高的人,另一方面也算是批评杀敌数低的人,起到了很好的效果. 所以,南将军经常问军师小工第i号士兵到第j号士兵中,杀敌数最高的人与杀敌数最低的人之间军功差值是多少. 现在,请你写一个程序,帮小工回答南将军每次的询问吧. 注意,南将军可能询问很多次. 输入 只有一组测试数据第一行是两个整数N,Q,其中N表示士兵的总数.Q表示南将军询

NYOJ士兵杀敌(三)

士兵杀敌(三) 时间限制:2000 ms  |  内存限制:65535 KB 难度:5 描述 南将军统率着N个士兵,士兵分别编号为1~N,南将军经常爱拿某一段编号内杀敌数最高的人与杀敌数最低的人进行比较,计算出两个人的杀敌数差值,用这种方法一方面能鼓舞杀敌数高的人,另一方面也算是批评杀敌数低的人,起到了很好的效果. 所以,南将军经常问军师小工第i号士兵到第j号士兵中,杀敌数最高的人与杀敌数最低的人之间军功差值是多少. 现在,请你写一个程序,帮小工回答南将军每次的询问吧. 注意,南将军可能询问很多

NYOJ 116 士兵杀敌 (线段树,区间和)

题目链接:NYOJ 116 士兵杀敌 士兵杀敌(二) 时间限制:1000 ms  |  内存限制:65535 KB 难度:5 描写叙述 南将军手下有N个士兵,分别编号1到N,这些士兵的杀敌数都是已知的. 小工是南将军手下的军师,南将军常常想知道第m号到第n号士兵的总杀敌数,请你帮助小工来回答南将军吧. 南将军的某次询问之后士兵i可能又杀敌q人,之后南将军再询问的时候.须要考虑到新增的杀敌数. 输入 仅仅有一组測试数据 第一行是两个整数N,M,当中N表示士兵的个数(1<N<1000000).M表

NYOJ 116 士兵杀敌(二) (线段树区间求和)

题目链接:NYOJ 116 士兵杀敌(二) 这一个是线段树的入门级水题,本题要求我们给出某个区间的区间和.这个问题和线段树的单点更新还是基本一致的.只要把单点更新中的值覆盖变为值得叠加,这一题便可以轻松解决了.如果不知道线段树的单点更新,请移步:传送门 [代码如下] #include <stdio.h> #include <string.h> #define MAXN 1<<21 //lg100000 约等于 21 typedef struct{ int left,ri

NYOJ 116 士兵杀敌(二)【线段树 单点更新】

题意:题意很清楚: 策略:如题. 这道题就是简单的线段树应用,据说还可以用树状数组来做,等我学了之后在说吧. 代码: #include<stdio.h> #include<string.h> #define LC l, m, rt<<1 #define RC m+1, r, rt<<1|1 #define LL long long #define MAXN 1000000 LL sum[MAXN<<2]; void PushUp(int rt)

NYOJ 119 士兵杀敌(三) RMQ ST

NYOJ 119 士兵杀敌(三) RMQ ST 题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=119 思路: ST在线 预处理O(nlogn) 查询O(1) 运行时间:828ms 代码: #include <iostream> #include <stdio.h> #include <string.h> #include <math.h> using namespace std; const in

nyoj 119 士兵杀敌(三)(RMQ)

士兵杀敌(三) 时间限制:2000 ms  |  内存限制:65535 KB 难度:5 描述 南将军统率着N个士兵,士兵分别编号为1~N,南将军经常爱拿某一段编号内杀敌数最高的人与杀敌数最低的人进行比较,计算出两个人的杀敌数差值,用这种方法一方面能鼓舞杀敌数高的人,另一方面也算是批评杀敌数低的人,起到了很好的效果. 所以,南将军经常问军师小工第i号士兵到第j号士兵中,杀敌数最高的人与杀敌数最低的人之间军功差值是多少. 现在,请你写一个程序,帮小工回答南将军每次的询问吧. 注意,南将军可能询问很多

nyoj 123 士兵杀敌(四)

士兵杀敌(四) 时间限制:2000 ms  |  内存限制:65535 KB 难度:5 描述 南将军麾下有百万精兵,现已知共有M个士兵,编号为1~M,每次有任务的时候,总会有一批编号连在一起人请战(编号相近的人经常在一块,相互之间比较熟悉),最终他们获得的军功,也将会平分到每个人身上,这样,有时候,计算他们中的哪一个人到底有多少军功就是一个比较困难的事情,军师小工的任务就是在南将军询问他某个人的军功的时候,快速的报出此人的军功,请你编写一个程序来帮助小工吧. 假设起始时所有人的军功都是0. 输入