第十一届“蓝狐网络杯”湖南省大学生计算机程序设计竞赛

后来才知道K题正式赛时没人AC,应该去做I题的。 o(╯□╰)o 


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])) 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;
}


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值