第十一届“蓝狐网络杯”湖南省大学生计算机程序设计竞赛
2016-01-26 18:38
701 查看
后来才知道K题正式赛时没人AC,应该去做I题的。 o(╯□╰)o
A题链接:A
没敢看。。。感觉是神题。
B题链接:B
处理出整数部分和小数部分,比较下就好了。
AC代码:
C题链接:C
感觉好繁琐。。。懒得写,我相信我写了也过不了 (ˇˍˇ) 想~
D题链接:D
怎么搞都能过。
AC代码:
E题链接:E
卡DFS?裸题
AC代码:
F题链接:F
思路:发现数最大为1e9,20个数连乘肯定会超的。因此只有20个情况,其实根本不到20。发现即使2个数连乘,数字最大不过100000,那么直接暴力就可以了。最后2-20不存在输出n 和 n-1就可以了。
忘了比较所有情况脑残一次。
AC代码:
G题链接:G
感觉神题
H题链接:H
模拟即可。
AC代码:
I题链接:I
比赛时没怎么看,好遗憾。
题意:给定n盏亮着的灯,有m个开关控制一些灯,给出一个m*n的矩阵,(i, j)元素为1表示i开关控制j灯。你必须选择num个连续的开关来关掉所有的灯,限制a <= num <= b。问有多少种方案。
思路:CF617E的变形,一次查询。用个string记录前缀异或和,遍历可能的末尾,扫描一次即可。
AC代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <vector>
#include <string>
#define INF 0x3f3f3f3f
#define eps 1e-8
#define MAXN (300000+10)
#define MAXM (300000+10)
#define Ri(a) scanf("%d", &a)
#define Rl(a) scanf("%lld", &a)
#define Rf(a) scanf("%lf", &a)
#define Rs(a) scanf("%s", a)
#define Pi(a) printf("%d\n", (a))
#define Pf(a) printf("%.2lf\n", (a))
#define Pl(a) printf("%lld\n", (a))
#define Ps(a) printf("%s\n", (a))
#define W(a) while((a)--)
#define CLR(a, b) memset(a, (b), sizeof(a))
#define MOD 1000000007
#define LL long long
#define lson o<<1, l, mid
#define rson o<<1|1, mid+1, r
#define ll o<<1
#define rr o<<1|1
#define PI acos(-1.0)
#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std;
string sum[MAXN];
map<string, int> cnt;
string solve(string x, string y, int n)
{
string z = "";
for(int i = 0; i < n; i++)
z += (x[i] - '0') ^ (y[i] - '0') + '0';
return z;
}
int main()
{
int kcase = 1, n, m, a, b;
while(scanf("%d%d%d%d", &n, &m, &a, &b) != EOF)
{
sum[0] = ""; string str = "";
for(int i = 1; i <= n; i++)
sum[0] += '0', str += '1';
for(int i = 1; i <= m; i++)
{
//cin >> str;
char ss[60]; Rs(ss);
sum[i] = solve(sum[i-1], ss, n);
//cout << sum[i] << endl;
}
LL ans = 0; cnt.clear();
for(int i = 1; i <= m; i++)
{
if(i >= a) cnt[sum[i-a]]++;
if(i > b) cnt[sum[i-b-1]]--;
if(i >= a)
{
string s = solve(str, sum[i], n);
//cout << s << endl;
ans += cnt[s];
}
}
printf("Case %d: %lld\n", kcase++, ans);
}
return 0;
}
J题链接:J
暴力就好了。
AC代码:
K题链接:K
RE成SB了。o(╯□╰)o,没有AC。。。 还是自己太弱。
题意:给出n个点(编号从1-n)和一个距离d以及q次查询,问你在区间[i, j]里面曼哈顿距离<=d的点有多少对。
没有AC的思路:建立2*4*108个树状数组,维护四条斜直线上点的个数。考虑一个点(x, y)做出的贡献,和它配对的点全部在点(x-d, y) (x, y+d) (x-d, y) (x, y-d)所围成的四边形里面,我们只需要维护四条边就可以了。每条直线均以x轴上的点为起点。q个区间从第一个区间开始移动,为了减少时间复杂度,先sort下。
代码:
A题链接:A
没敢看。。。感觉是神题。
B题链接:B
处理出整数部分和小数部分,比较下就好了。
AC代码:
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <cstdlib> #include <algorithm> #include <queue> #include <stack> #include <map> #include <set> #include <vector> #include <string> #define INF 0x3f3f3f3f #define eps 1e-8 #define MAXN (1000+10) #define MAXM (200000+10) #define Ri(a) scanf("%d", &a) #define Rl(a) scanf("%lld", &a) #define Rf(a) scanf("%lf", &a) #define Rs(a) scanf("%s", a) #define Pi(a) printf("%d\n", (a)) #define Pf(a) printf("%.2lf\n", (a)) #define Pl(a) printf("%lld\n", (a)) #define Ps(a) printf("%s\n", (a)) #define W(a) while((a)--) #define CLR(a, b) memset(a, (b), sizeof(a)) #define MOD 1000000007 #define LL long long #define lson o<<1, l, mid #define rson o<<1|1, mid+1, r #define ll o<<1 #define rr o<<1|1 #define PI acos(-1.0) using namespace std; char a[110], b[110]; char aa1[110], aa2[110]; char bb1[110], bb2[110]; int main() { int kcase = 1; while(scanf("%s%s", a, b) != EOF) { int la = strlen(a); int i; for(i = la-1; i >= 0; i--) { if(a[i] != '0') break; if(a[i] == '.') {i--; break;} } a[i+1] = 0; la = i+1; int lb = strlen(b); for(i = lb-1; i >= 0; i--) { if(b[i] != '0') break; if(b[i] == '.') {i--; break;} } b[i+1] = 0; lb = i+1; int la1 = 0; for(i = 0; i < la; i++) { if(a[i] == '.') break; aa1[la1++] = a[i]; } aa1[la1] = 0; i++; int la2 = 0; for(; i < la; i++) aa2[la2++] = a[i]; aa2[la2] = 0; int lb1 = 0, lb2 = 0; for(i = 0; i < lb; i++) { if(b[i] == '.') break; bb1[lb1++] = b[i]; } i++; bb1[lb1] = 0; for(; i < lb; i++) bb2[lb2++] = b[i]; bb2[lb2] = 0; if(la1 < lb1) printf("Case %d: Smaller\n", kcase++); else if(la1 > lb1) printf("Case %d: Bigger\n", kcase++); else { if(strcmp(aa1, bb1) < 0) printf("Case %d: Smaller\n", kcase++); else if(strcmp(aa1, bb1) > 0) printf("Case %d: Bigger\n", kcase++); else { if(strcmp(aa2, bb2) < 0) printf("Case %d: Smaller\n", kcase++); else if(strcmp(aa2, bb2) > 0) printf("Case %d: Bigger\n", kcase++); else printf("Case %d: Same\n", kcase++); } } } return 0; }
C题链接:C
感觉好繁琐。。。懒得写,我相信我写了也过不了 (ˇˍˇ) 想~
D题链接:D
怎么搞都能过。
AC代码:
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <cstdlib> #include <algorithm> #include <queue> #include <stack> #include <map> #include <set> #include <vector> #include <string> #define INF 0x3f3f3f3f #define eps 1e-8 #define MAXN (10000+10) #define MAXM (200000+10) #define Ri(a) scanf("%d", &a) #define Rl(a) scanf("%lld", &a) #define Rf(a) scanf("%lf", &a) #define Rs(a) scanf("%s", a) #define Pi(a) printf("%d\n", (a)) #define Pf(a) printf("%.2lf\n", (a)) #define Pl(a) printf("%lld\n", (a)) #define Ps(a) printf("%s\n", (a)) #define W(a) while((a)--) #define CLR(a, b) memset(a, (b), sizeof(a)) #define MOD 1000000007 #define LL long long #define lson o<<1, l, mid #define rson o<<1|1, mid+1, r #define ll o<<1 #define rr o<<1|1 #define PI acos(-1.0) using namespace std; int ans[600][600]; int row[600], cul[600]; int Map[600][600]; int main() { int n, m, kcase = 1; while(scanf("%d%d", &n, &m) != EOF) { for(int i = 1; i <= n; i++) { row[i] = 0; for(int j = 1; j <= m; j++) Ri(Map[i][j]), row[i] += Map[i][j]; } for(int j = 1; j <= m; j++) { cul[j] = 0; for(int i = 1; i <= n; i++) cul[j] += Map[i][j]; } int wrow, wcul; int Max = 0; for(int i = 1; i <= n; i++) { if(Max < row[i]) { Max = row[i]; wrow = i; } } Max = 0; for(int i = 1; i <= m; i++) { if(Max < cul[i]) { Max = cul[i]; wcul = i; } } bool flag = false; int Mans = 0; for(int i = 1; i <= n; i++) { for(int j = 1; j <= m; j++) { int ans = row[i] + cul[j] - Map[i][j]; Mans = max(Mans, ans); } } for(int i = 1; i <= n; i++) { for(int j = 1; j <= m; j++) { int ans = row[i] + cul[j] - Map[i][j]; if(Mans == ans && i == wrow && j == wcul) { flag = true; break; } } if(flag) break; } if(flag) printf("Case %d: Weak\n", kcase++); else printf("Case %d: Strong\n", kcase++); } return 0; }
E题链接:E
卡DFS?裸题
AC代码:
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <cstdlib> #include <algorithm> #include <queue> #include <stack> #include <map> #include <set> #include <vector> #include <string> #define INF 0x3f3f3f3f #define eps 1e-8 #define MAXN (10000+10) #define MAXM (300000+10) #define Ri(a) scanf("%d", &a) #define Rl(a) scanf("%lld", &a) #define Rf(a) scanf("%lf", &a) #define Rs(a) scanf("%s", a) #define Pi(a) printf("%d\n", (a)) #define Pf(a) printf("%.2lf\n", (a)) #define Pl(a) printf("%lld\n", (a)) #define Ps(a) printf("%s\n", (a)) #define W(a) while((a)--) #define CLR(a, b) memset(a, (b), sizeof(a)) #define MOD 1000000007 #define LL long long #define lson o<<1, l, mid #define rson o<<1|1, mid+1, r #define ll o<<1 #define rr o<<1|1 #define PI acos(-1.0) using namespace std; int Map[501][501]; int n, m; bool judge(int x, int y){ return x >= 0 && x < n && y >= 0 && y < m; } int ans1, ans2; int Move[4][2] = {0,1, 0,-1, 1,0, -1,0}; bool vis[501][501]; //void DFS1(int x, int y, int ex, int ey, int val) //{ // if(x == ex && y == ey) // { // ans1 = min(ans1, val); // return ; // } // for(int k = 0; k < 4; k++) // { // int xx = x + Move[k][0]; // int yy = y + Move[k][1]; // if(!judge(xx, yy) || vis[xx][yy] || Map[xx][yy] == -1) continue; // vis[xx][yy] = true; // DFS1(xx, yy, ex, ey, val + Map[xx][yy]); // vis[xx][yy] = false; // } //} bool use[501][501][4]; struct Node{ int x, y, op, sum; friend bool operator < (Node a, Node b){ return a.sum > b.sum; } }; void BFS1(int sx, int sy, int ex, int ey, int val) { Node now, next; priority_queue<Node> Q; now.x = sx, now.y = sy, now.sum = val; Q.push(now); while(!Q.empty()) { now = Q.top(); Q.pop(); if(now.x == ex && now.y == ey) { ans1 = now.sum; return ; } for(int k = 0; k < 4; k++) { if(k == now.op) continue; int xx = now.x + Move[k][0]; int yy = now.y + Move[k][1]; if(!judge(xx, yy) || Map[xx][yy] == -1 || vis[xx][yy]) continue; next.x = xx, next.y = yy, next.sum = now.sum + Map[xx][yy]; Q.push(next); vis[xx][yy] = true; } } } void BFS2(int sx, int sy, int ex, int ey, int op, int val) { Node now, next; priority_queue<Node> Q; now.x = sx, now.y = sy, now.sum = val, now.op = -1; Q.push(now); while(!Q.empty()) { now = Q.top(); Q.pop(); if(now.x == ex && now.y == ey) { ans2 = now.sum; return ; } for(int k = 0; k < 4; k++) { if(k == now.op) continue; int xx = now.x + Move[k][0]; int yy = now.y + Move[k][1]; if(!judge(xx, yy) || Map[xx][yy] == -1 || use[now.x][now.y][k]) continue; next.x = xx, next.y = yy, next.sum = now.sum + Map[xx][yy]; next.op = k; Q.push(next); use[now.x][now.y][k] = true; } } } //void DFS2(int x, int y, int ex, int ey, int op, int val) //{ // if(x == ex && y == ey) // { // ans2 = min(ans2, val); // return ; // } // for(int k = 0; k < 4; k++) // { // if(k == op) continue; // int xx = x + Move[k][0]; // int yy = y + Move[k][1]; // if(!judge(xx, yy) || Map[xx][yy] == -1 || use[x][y][k]) continue; // use[x][y][k] = true; // DFS2(xx, yy, ex, ey, k, val + Map[xx][yy]); // use[x][y][k] = false; // } //} int main() { int kcase= 1, x1, y1, x2, y2; while(scanf("%d%d%d%d%d%d", &n, &m, &x1, &y1, &x2, &y2) != EOF) { x1--, y1--, x2--, y2--; for(int i = 0; i < n; i++) { for(int j = 0; j < m; j++) { char str[10]; Rs(str); if(str[0] == '*') {Map[i][j]= -1; continue;} int len = strlen(str); int val = 0; for(int k = 0; k < len; k++) val = val * 10 + (str[k] - '0'); Map[i][j] = val; } } ans1 = ans2 = INF; CLR(vis, false); vis[x1][y1] = true; BFS1(x1, y1, x2, y2, Map[x1][y1]); CLR(use, false); BFS2(x1, y1, x2, y2, -1, Map[x1][y1]); if(ans1 == INF) ans1 = -1; if(ans2 == INF) ans2 = -1; printf("Case %d: %d %d\n", kcase++, ans1, ans2); } return 0; }
F题链接:F
思路:发现数最大为1e9,20个数连乘肯定会超的。因此只有20个情况,其实根本不到20。发现即使2个数连乘,数字最大不过100000,那么直接暴力就可以了。最后2-20不存在输出n 和 n-1就可以了。
忘了比较所有情况脑残一次。
AC代码:
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <cstdlib> #include <algorithm> #include <queue> #include <stack> #include <map> #include <set> #include <vector> #include <string> #define INF 0x3f3f3f3f #define eps 1e-8 #define MAXN (10000+10) #define MAXM (300000+10) #define Ri(a) scanf("%d", &a) #define Rl(a) scanf("%lld", &a) #define Rf(a) scanf("%lf", &a) #define Rs(a) scanf("%s", a) #define Pi(a) printf("%d\n", (a)) #define Pf(a) printf("%.2lf\n", (a)) #define Pl(a) printf("%lld\n", (a)) #define Ps(a) printf("%s\n", (a)) #define W(a) while((a)--) #define CLR(a, b) memset(a, (b), sizeof(a)) #define MOD 1000000007 #define LL long long #define lson o<<1, l, mid #define rson o<<1|1, mid+1, r #define ll o<<1 #define rr o<<1|1 #define PI acos(-1.0) using namespace std; int main() { int n, kcase = 1; while(Ri(n) != EOF) { if(n == 1) { printf("Case %d: Impossible\n", kcase++); continue; } bool flag = false; int a = INF, b; LL val = 1LL * n; for(int bit = 20; bit >= 2; bit--) { int Max; if(bit > 5) Max = 100; else if(bit == 5) Max = 100; else if(bit == 4) Max = 1000; else if(bit == 3) Max = 1000; else if(bit == 2) Max = 100000; for(int i = bit+1; i <= Max; i++) { LL sum = 1LL; for(int j = 0; j < bit; j++) sum = sum * (i-j); if(sum > n) break; if(sum == val) { flag = true; if(a > i) { a = i; b = i-bit; } } } } if(flag) printf("Case %d: %d %d\n", kcase++, a, b); else printf("Case %d: %d %d\n", kcase++, n, n-1); } return 0; }
G题链接:G
感觉神题
H题链接:H
模拟即可。
AC代码:
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <cstdlib> #include <algorithm> #include <queue> #include <stack> #include <map> #include <set> #include <vector> #include <string> #define INF 0x3f3f3f3f #define eps 1e-8 #define MAXN (10000+10) #define MAXM (300000+10) #define Ri(a) scanf("%d", &a) #define Rl(a) scanf("%lld", &a) #define Rf(a) scanf("%lf", &a) #define Rs(a) scanf("%s", a) #define Pi(a) printf("%d\n", (a)) #define Pf(a) printf("%.2lf\n", (a)) #define Pl(a) printf("%lld\n", (a)) #define Ps(a) printf("%s\n", (a)) #define W(a) while((a)--) #define CLR(a, b) memset(a, (b), sizeof(a)) #define MOD 1000000007 #define LL long long #define lson o<<1, l, mid #define rson o<<1|1, mid+1, r #define ll o<<1 #define rr o<<1|1 #define PI acos(-1.0) using namespace std; char str[110][1010]; char name1[110][1010]; char name2[110][1010]; map<string, int> fp; map<int, string> tp; char Map[1100][1010]; bool judge(char *s) { int len = strlen(s); for(int i = 0; i < len; i+=2) { if(s[i] != 'h' || s[i+1] != 'e') return false; } return true; } int main() { int n = 0; while(gets(str )) n++; int total = 0; for(int i = 0; i < n; i++) { int top = 0; int j; for(j = 0; str[i][j] != '-'; j++) name1[i][top++] = str[i][j]; name1[i][top] = 0; if(!fp[name1[i]]) fp[name1[i]] = ++total, tp[total] = name1[i]; j += 2; top = 0; for(; str[i][j] != ':'; j++) name2[i][top++] = str[i][j]; if(!fp[name2[i]]) fp[name2[i]] = ++total, tp[total] = name2[i]; } int cnt = 0, ans = 0; for(int i = 1; i <= total; i++) { for(int j = i; j <= total; j++) { for(int k = n-1; k >= 0; k--) { int u = fp[name1[k]]; int v = fp[name2[k]]; if(i == u && j == v || i == v && j == u) { ++cnt; strcpy(Map[cnt], str[k]); break; } } } } for(int i = 1; i <= cnt; i++) { int len = strlen(Map[i]); int j; for(j = 0; j < len; j++) { if(Map[i][j] == ':') break; } j += 2; char s[1010]; int top = 0; for(; j < len; j++) { if(Map[i][j] >= 'A' && Map[i][j] <= 'Z') Map[i][j] += 32; if(Map[i][j] >= 'a' && Map[i][j] <= 'z') s[top++] = Map[i][j]; if(Map[i][j] >= 'a' && Map[i][j] <= 'z' && !(Map[i][j+1] >= 'a' && Map[i][j+1] <= 'z')) { s[top] = 0; //Ps(s); if(judge(s)) { ans++; break; } top = 0; } } } printf("%.0lf%%\n", ans * 1.0 / cnt * 100); return 0; }
I题链接:I
比赛时没怎么看,好遗憾。
题意:给定n盏亮着的灯,有m个开关控制一些灯,给出一个m*n的矩阵,(i, j)元素为1表示i开关控制j灯。你必须选择num个连续的开关来关掉所有的灯,限制a <= num <= b。问有多少种方案。
思路:CF617E的变形,一次查询。用个string记录前缀异或和,遍历可能的末尾,扫描一次即可。
AC代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <vector>
#include <string>
#define INF 0x3f3f3f3f
#define eps 1e-8
#define MAXN (300000+10)
#define MAXM (300000+10)
#define Ri(a) scanf("%d", &a)
#define Rl(a) scanf("%lld", &a)
#define Rf(a) scanf("%lf", &a)
#define Rs(a) scanf("%s", a)
#define Pi(a) printf("%d\n", (a))
#define Pf(a) printf("%.2lf\n", (a))
#define Pl(a) printf("%lld\n", (a))
#define Ps(a) printf("%s\n", (a))
#define W(a) while((a)--)
#define CLR(a, b) memset(a, (b), sizeof(a))
#define MOD 1000000007
#define LL long long
#define lson o<<1, l, mid
#define rson o<<1|1, mid+1, r
#define ll o<<1
#define rr o<<1|1
#define PI acos(-1.0)
#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std;
string sum[MAXN];
map<string, int> cnt;
string solve(string x, string y, int n)
{
string z = "";
for(int i = 0; i < n; i++)
z += (x[i] - '0') ^ (y[i] - '0') + '0';
return z;
}
int main()
{
int kcase = 1, n, m, a, b;
while(scanf("%d%d%d%d", &n, &m, &a, &b) != EOF)
{
sum[0] = ""; string str = "";
for(int i = 1; i <= n; i++)
sum[0] += '0', str += '1';
for(int i = 1; i <= m; i++)
{
//cin >> str;
char ss[60]; Rs(ss);
sum[i] = solve(sum[i-1], ss, n);
//cout << sum[i] << endl;
}
LL ans = 0; cnt.clear();
for(int i = 1; i <= m; i++)
{
if(i >= a) cnt[sum[i-a]]++;
if(i > b) cnt[sum[i-b-1]]--;
if(i >= a)
{
string s = solve(str, sum[i], n);
//cout << s << endl;
ans += cnt[s];
}
}
printf("Case %d: %lld\n", kcase++, ans);
}
return 0;
}
J题链接:J
暴力就好了。
AC代码:
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <cstdlib> #include <algorithm> #include <queue> #include <stack> #include <map> #include <set> #include <vector> #include <string> #define INF 0x3f3f3f3f #define eps 1e-8 #define MAXN (10000+10) #define MAXM (200000+10) #define Ri(a) scanf("%d", &a) #define Rl(a) scanf("%lld", &a) #define Rf(a) scanf("%lf", &a) #define Rs(a) scanf("%s", a) #define Pi(a) printf("%d\n", (a)) #define Pf(a) printf("%.2lf\n", (a)) #define Pl(a) printf("%lld\n", (a)) #define Ps(a) printf("%s\n", (a)) #define W(a) while((a)--) #define CLR(a, b) memset(a, (b), sizeof(a)) #define MOD 1000000007 #define LL long long #define lson o<<1, l, mid #define rson o<<1|1, mid+1, r #define ll o<<1 #define rr o<<1|1 #define PI acos(-1.0) using namespace std; bool vis[MAXN], use[MAXN]; void get() { for(int i = 32; i < 100; i++) vis[i * i] = true; } int a[10]; int solve(int i, int j) { int sum = 0; for(int k = 1; k <= 4; k++) { if(k == i) sum = sum * 10 + j; else sum = sum * 10 + a[k]; } return sum; } int main() { CLR(vis, false); get(); int t, kcase = 1; Ri(t); W(t) { char str[10]; Rs(str); for(int i = 0; i < 4; i++) a[i+1] = str[i] - '0'; CLR(use, false); int ans = 0; for(int i = 1; i <= 4; i++) { for(int j = 0; j <= 9; j++) { if(i == 1 && j == 0) continue; if(a[i] == j) continue; int val = solve(i, j); if(use[val]) continue; if(vis[val]) ans++; use[val] = true; } } printf("Case %d: %d\n", kcase++, ans); } return 0; }
K题链接:K
RE成SB了。o(╯□╰)o,没有AC。。。 还是自己太弱。
题意:给出n个点(编号从1-n)和一个距离d以及q次查询,问你在区间[i, j]里面曼哈顿距离<=d的点有多少对。
没有AC的思路:建立2*4*108个树状数组,维护四条斜直线上点的个数。考虑一个点(x, y)做出的贡献,和它配对的点全部在点(x-d, y) (x, y+d) (x-d, y) (x, y-d)所围成的四边形里面,我们只需要维护四条边就可以了。每条直线均以x轴上的点为起点。q个区间从第一个区间开始移动,为了减少时间复杂度,先sort下。
代码:
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <cstdlib> #include <algorithm> #include <queue> #include <stack> #include <map> #include <set> #include <vector> #include <string> #define INF 0x3f3f3f3f #define eps 1e-8 #define MAXN (200000+10) #define MAXM (300000+10) #define Ri(a) scanf("%d", &a) #define Rl(a) scanf("%lld", &a) #define Rf(a) scanf("%lf", &a) #define Rs(a) scanf("%s", a) #define Pi(a) printf("%d\n", (a)) #define Pf(a) printf("%.2lf\n", (a)) #define Pl(a) printf("%lld\n", (a)) #define Ps(a) printf("%s\n", (a)) #define W(a) while((a)--) #define CLR(a, b) memset(a, (b), sizeof(a)) #define MOD 1000000007 #define LL long long #define lson o<<1, l, mid #define rson o<<1|1, mid+1, r #define ll o<<1 #define rr o<<1|1 #define PI acos(-1.0) #pragma comment(linker, "/STACK:102400000,102400000") using namespace std; int C1[800][4][800], C2[800][4][800]; int zero[4][800]; int lowbit(int x){ return x & (-x); } void Update(int pos, int op, int x, int d) { if(pos < 0) { pos = -pos; while(x <= 800) { C1[pos][op][x] += d; x += lowbit(x); } } else if(pos > 0) { while(x <= 800) { C2[pos][op][x] += d; x += lowbit(x); } } else { while(x <= 800) { zero[op][x] += d; x += lowbit(x); } } } LL Sum(int pos, int op, int x) { LL s = 0; if(pos < 0) { pos = -pos; while(x > 0) { s += 1LL * C1[pos][op][x]; x -= lowbit(x); } } else if(pos > 0) { while(x > 0) { s += 1LL * C2[pos][op][x]; x -= lowbit(x); } } else { while(x > 0) { s += 1LL * zero[op][x]; x -= lowbit(x); } } return s; } LL sum = 0; void solve(int x, int y, int d, int op) { int pos, l, r; if(op == -1) { if(y == 0) { Update(x, 0, 1, op); Update(x, 1, 1, op); Update(x, 2, 1, op); Update(x, 3, 1, op); } else if(y > 0) { Update(x - y, 0, y + 1, op); Update(x + y, 3, y + 1, op); } else { Update(x + y, 1, 1 - y, op); Update(x - y, 2, 1 - y, op); } } for(int i = 1; i <= d; i++) { int Minx = x - i, Maxx = x + i; int Miny = y - i, Maxy = y + i; pos = x - Maxy, l = Minx - pos + 1, r = x - pos + 1; sum += 1LL * (Sum(pos, 0, r) - Sum(pos, 0, l-1)) * op; pos = Maxx - y, l = pos - Maxx + 1, r = pos - x + 1; sum += 1LL * (Sum(pos, 1, r) - Sum(pos, 1, l-1)) * op; pos = Minx + y, l = Minx - pos + 1, r = x - pos + 1; sum += 1LL * (Sum(pos, 2, r) - Sum(pos, 2, l-1)) * op; sum -= 1LL * (Sum(pos, 2, l) - Sum(pos, 2, l-1)) * op; sum -= 1LL * (Sum(pos, 2, r) - Sum(pos, 2, r-1)) * op; pos = Maxx + y, l = pos - Maxx + 1, r = pos - x + 1; sum += 1LL * (Sum(pos, 3, r) - Sum(pos, 3, l-1)) * op; sum -= 1LL * (Sum(pos, 3, l) - Sum(pos, 3, l-1)) * op; sum -= 1LL * (Sum(pos, 3, r) - Sum(pos, 3, r-1)) * op; } if(y == 0) sum += 1LL * Sum(x, 0, 1) * op; else if(y > 0) sum += 1LL * (Sum(x - y, 0, y + 1) - Sum(x - y, 0, y)) * op; else sum += 1LL * (Sum(x + y, 1, 1 - y) - Sum(x + y, 1, -y)) * op; if(op == 1) { if(y == 0) { Update(x, 0, 1, op); Update(x, 1, 1, op); Update(x, 2, 1, op); Update(x, 3, 1, op); } else if(y > 0) { Update(x - y, 0, y + 1, op); Update(x + y, 3, y + 1, op); } else { Update(x + y, 1, 1 - y, op); Update(x - y, 2, 1 - y, op); } } } struct Node{ int l, r, id; }; Node num[10000+10]; int top = 500; bool cmp(Node a, Node b){ if(a.l / top != b.l / top) return a.l / top < b.l / top; else return a.r < b.r; } int x[MAXN], y[MAXN]; LL ans[10000+10]; int main() { int kcase = 1, n, d, q; while(scanf("%d%d%d", &n, &d, &q) != EOF) { for(int i = 1; i <= n; i++) Ri(x[i]), Ri(y[i]); for(int i = 1; i <= q; i++) Ri(num[i].l), Ri(num[i].r), num[i].id = i;// num[i].l--; sort(num+1, num+q+1, cmp); int L = num[1].l, R = num[1].r; sum = 0; CLR(C1, 0); CLR(C2, 0); CLR(zero, 0); for(int i = L; i <= R; i++) solve(x[i], y[i], d, 1); ans[num[1].id] = sum; for(int i = 2; i <= q; i++) { while(L > num[i].l) { L--; solve(x[L], y[L], d, 1); } while(L < num[i].l) { solve(x[L], y[L], d, -1); L++; } while(R < num[i].r) { R++; solve(x[R], y[R], d, 1); } while(R > num[i].r) { solve(x[R], y[R], d, -1); R--; } ans[num[i].id] = sum; } printf("Case %d:\n", kcase++); for(int i = 1; i <= q; i++) Pl(ans[i]); } return 0; }
相关文章推荐
- http长连接和短连接
- gerrit+http+2
- 人工神经网络
- iOS 关于ASIHTTPRequest
- windows server网络共享权限设置
- meta http-equiv='refresh' 解读
- IOS中显示和隐藏状态栏的网络活动标志
- 关于TCP的粘包问题
- iOS两种检测网络状态的方法
- HTTP,TCP/IP,Socket
- TCP Header
- HTTP协议详解
- HTTP Keep-Alive详解
- 黑马程序猿 ---------- Java网络技术之 ---正則表達式 (Day06)
- loadrunner简单使用——HTTP,WebService,Socket压力测试脚本编写
- HttpModel 和 HttpHandle
- Android网络:封装自用网络层的心得体会
- ios tcp multipath
- Hbulider中,QQ分享到好友,总是提示,分享失败,请检查网络并重试
- TCP滑动窗口机制