CF Gym 101955G Best ACMer Solves the Hardest Problem

链接:https://codeforces.com/gym/101955/problem/G

题意:在二维平面上四种操作: 1,加一个带权的点; 2,删去一个点; 3,给一个点周围欧几里得距离为sqrt(k)的存在的点点权都加w; 4,查询一个到点欧几里得距离为sqrtk的点权和。

   x, y<6000, k<1e7, sigma(询问次数)<1e6,time:12s

题解:原本以为是数据结构,发现距离为k的x,y其实不多,直接存vector<pii>dis[maxk]暴力即可。

   注意:要判断nx,ny范围是否溢出,还有就是能不用memset尽量不要用,会超时。

#include <bits/stdc++.h>
using namespace std;

typedef pair<int, int> pii;

const int mod=6e3;
const int maxk=1e7+5;
const int maxn=6e3+5;

vector<pii> dis[maxk];
int vis[maxn][maxn], val[maxn][maxn];
int T, kase=0;

void pre_dis()
{
    for(int x=0; x<=3200; x++)
        for(int y=0; y<=3200; y++)
        {
            if(x*x+y*y>maxk) continue;
            dis[x*x+y*y].push_back(pii(x, y));
        }
}

void ins(int x, int y, int w)
{
    val[x][y]=w; vis[x][y]=kase;
}

void del(int x, int y)
{
    vis[x][y]=false;
}

bool check(int x, int y)
{
    if(x<0 || x>6000 || y<0 || y>6000) return false;
    if(vis[x][y]==kase) return true;
    return false;
}

void add(int x, int y, int k, int w)
{
    for(int i=0; i<dis[k].size(); i++)
    {
        int dx=dis[k][i].first, dy=dis[k][i].second;
        if(check(x+dx,y+dy)){
            val[x+dx][y+dy]+=w;
        }
        if(dx!=0 && check(x-dx,y+dy)){
            val[x-dx][y+dy]+=w;
        }
        if(dy!=0 && check(x+dx,y-dy)){
            val[x+dx][y-dy]+=w;
        }
        if(dx!=0&&dy!=0 && check(x-dx,y-dy)){
            val[x-dx][y-dy]+=w;
        }
    }
}

long long ask(int x, int y, int k)
{
    long long res=0;
    for(int i=0; i<dis[k].size(); i++)
    {
        int dx=dis[k][i].first, dy=dis[k][i].second;
        if(check(x+dx,y+dy)){
            res+=val[x+dx][y+dy];
        }
        if(dx!=0 && check(x-dx,y+dy)){
            res+=val[x-dx][y+dy];
        }
        if(dy!=0 && check(x+dx,y-dy)){
            res+=val[x+dx][y-dy];
        }
        if(dx!=0&&dy!=0 && check(x-dx,y-dy)){
            res+=val[x-dx][y-dy];
        }
    }
    return res;
}

int main()
{
    //freopen("in.txt", "r", stdin);
    pre_dis();
    for(scanf("%d", &T); T--; )
    {
        printf("Case #%d:\n", ++kase);
        //memset(vis, false, sizeof(vis)); 加上这句会超时
        int n, m;
        long long lastans=0;
        scanf("%d%d", &n, &m);
        for(int i=0; i<n; i++)
        {
            int x, y, w;
            scanf("%d%d%d", &x, &y, &w);
            ins(x, y, w);
        }
        for(int i=0; i<m; i++)
        {
            int cmd, x, y, w, k;
            scanf("%d%d%d", &cmd, &x, &y);
            x=(x+lastans)%mod+1;
            y=(y+lastans)%mod+1;
            if(cmd==1){
                scanf("%d", &w);
                ins(x, y, w);
            }
            else if(cmd==2){
                del(x, y);
            }
            else if(cmd==3){
                scanf("%d%d", &k, &w);
                add(x, y, k, w);
            }
            else if(cmd==4){
                scanf("%d", &k);
                printf("%I64d\n", lastans=ask(x, y, k));
            }
        }
    }
    return 0;
}

原文地址:https://www.cnblogs.com/Yokel062/p/11650122.html

时间: 2024-10-11 11:03:40

CF Gym 101955G Best ACMer Solves the Hardest Problem的相关文章

CF gym 101933 K King&#39;s Colors —— 二项式反演

题目:http://codeforces.com/gym/101933/problem/K 其实每个点的颜色只要和父亲不一样即可: 所以至多 i 种颜色就是 \( i * (i-1)^{n-1} \),设为 \( f(i) \),设恰好 i 种颜色为 \( g(i) \) 那么 \( f(i) = \sum\limits_{j=0}^{i} C_{i}^{j} * g(j) \) 二项式反演得到 \( g(i) = \sum\limits_{j=0}^{k} (-1)^{k-j} * C_{k}

The Hardest Problem Ever(杭电1048)

/*The Hardest Problem Ever Problem Description Julius Caesar lived in a time of danger and intrigue. The hardest situation Caesar ever faced was keeping himself alive. In order for him to survive, he decided to create one of the first ciphers. This c

JAVA HDU 1048 The Hardest Problem Ever

题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=1048 1 package hdu; 2 3 import java.io.BufferedInputStream; 4 import java.util.Scanner; 5 6 public class hdu_1048 { 7 8 public static void main(String[] args) { 9 Scanner in = new Scanner(new BufferedInp

HDU 1048.The Hardest Problem Ever【字符串处理】【8月25】

The Hardest Problem Ever Problem Description Julius Caesar lived in a time of danger and intrigue. The hardest situation Caesar ever faced was keeping himself alive. In order for him to survive, he decided to create one of the first ciphers. This cip

HDU-1048-The Hardest Problem Ever(C++ &amp;&amp; 偶尔一水......)

The Hardest Problem Ever Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 19343    Accepted Submission(s): 9061 Problem Description Julius Caesar lived in a time of danger and intrigue. The hard

HDU1048 The Hardest Problem Ever

The Hardest Problem Ever Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 15790    Accepted Submission(s): 7298 Problem Description Julius Caesar lived in a time of danger and intrigue. The hard

(字符串 枚举)The Hardest Problem Ever hdu1048

The Hardest Problem Ever 链接:http://acm.hdu.edu.cn/showproblem.php?pid=1048 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 31307    Accepted Submission(s): 14491 Problem Description Julius Caesa

cf 1174 D Ehab and the Expected XOR Problem

cf 1174 D Ehab and the Expected XOR Problem 题意 在1~\(2^n\)范围内找到一个最长的序列,使得该序列的每一个子串异或后不等于0和x 题解 假设该序列为a,那么前缀异或和b[i] = a[i]^a[i-1]^...^a[0],如果b之间异或都不会等于0和x,那么a之间也不会. #include <cstdio> #include <cstring> int main() { int n, x; while(~scanf("%

CF Gym 102059E Electronic Circuit (set存图删点)

链接:https://codeforces.com/gym/102059/problem/E 题意:n个点, m条线,问这个电路是否合法,合法:可以确定一个起点和一个终点. 题解:不断的删点,删除度数为2的点,再相连,看最终度数为1的点的个数是否为2.set存图 #include <bits/stdc++.h> using namespace std; const int maxn=3e5+5; set<int> S[maxn]; int n, m; void del_edge()