列表

详情


NC247070. 233的网格图

描述

初始给出n,k,q,代表有n个点,第i个点坐标(x_i,y_i),两点(i,j)之间距离

进行以下三种操作q

* 1 代表查询有多少点对(i,j)满足

* 2 u 代表修改

* 3 o a b 代表修改

输入描述

第一行三个正整数n,k,q

接下来n行每行两个正整数代表x_i,y_i



接下来q行代表操作,格式如题面所写

输出描述

对于每个1操作输出一行一个数代表答案

示例1

输入:

4 2 5
1 2
3 4
2 5
6 3
1
3 1 2 3
1
2 2
1

输出:

3
5
6

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++(g++ 7.5.0) 解法, 执行用时: 3363ms, 内存消耗: 834640K, 提交时间: 2022-12-10 12:01:27

#include<bits/stdc++.h>
using namespace std;
template <typename T> inline void read(T &x)
{
	x=0;short f=1;char c=getchar();
	for(;c<'0'||c>'9';c=getchar()) if(c=='-') f=-1;
	for(;c>='0'&&c<='9';c=getchar()) x=(x<<1)+(x<<3)+(c^48);
	x*=f;return;
}
const int max_n=1e5+5;
int x[max_n],y[max_n];
const int V=1e4;
const int R=2*V+1;
const int max_R=R+5;
namespace BIT{
    int val[max_R][max_R];
    inline void add(int x,int y,int v)
    {
        for(int i=x;i<=R;i+=i&(-i))
            for(int j=y;j<=R;j+=j&(-j))
                val[i][j]+=v;
    }
    inline int query(int x,int y)
    {
        int res=0;
        for(int i=x;i>0;i-=i&(-i))
            for(int j=y;j>0;j-=j&(-j))
                res+=val[i][j];
        return res;
    }
}
inline int query(int a,int b,int c,int d)
{
    a=max(a,1),b=min(b,R),c=max(c,1),d=min(d,R);
    if(a>b||c>d)
        return 0;
    return BIT::query(b,d)-BIT::query(a-1,d)-BIT::query(b,c-1)+BIT::query(a-1,c-1);
}
int n,k,q;
inline int calc(int x,int y)
{
    int a1=x-k,b1=x+k,c1=y-k,d1=y+k;
    int res=query(a1,b1,c1,d1);
    int a=(x+y-V-2)>>1,b=x-a-1;
    swap(a,b);
    x=a+b+1,y=a-b+V+1;
    int a2=x-k,b2=x+k,c2=y-k,d2=y+k;
    res+=query(a2,b2,c2,d2);
    res-=query(max(a1,a2),min(b1,b2),max(c1,c2),min(d1,d2));
    return res;
}
long long ans;
inline void calc()
{
    ans=0;
    for(int i=1;i<=n;++i)
        ans+=calc(x[i],y[i]);
}
int main()
{
    scanf("%d%d%d",&n,&k,&q);
    for(int i=1;i<=n;++i)
    {
        int a,b;
        scanf("%d%d",&a,&b);
        x[i]=a+b+1,y[i]=a-b+V+1;
        BIT::add(x[i],y[i],1);
    }
    calc();
    const int lim=2e4;
    while(q--)
    {
        int opt;
        scanf("%d",&opt);
        if(opt==1)
        {
            if(k<=lim)
                printf("%lld\n",(ans-n)>>1);
            else
                printf("%lld\n",n*(n-1ll)>>1);
        }
        else if(opt==2)
        {
            int u;
            scanf("%d",&u);
            if(u==1)
                continue;
            if(k<=lim)
            {
                k*=u;
                if(k<=lim)
                    calc();
            }
        }
        else
        {
            int o,a,b;
            scanf("%d%d%d",&o,&a,&b);
            if(k<=lim)
            {
                ans-=calc(x[o],y[o])*2-1;
                BIT::add(x[o],y[o],-1);
                x[o]=a+b+1,y[o]=a-b+V+1;
                BIT::add(x[o],y[o],1);
                ans+=calc(x[o],y[o])*2-1;
            }
        }
    }
    return 0;
}

C++(clang++ 11.0.1) 解法, 执行用时: 3902ms, 内存消耗: 832492K, 提交时间: 2022-12-09 21:48:32

#include<bits/stdc++.h>
using namespace std;
const int max_n=1e5+5;
int x[max_n],y[max_n];
const int V=1e4;
const int R=2*V+1;
const int max_R=R+5;
namespace BIT
{
	int val[max_R][max_R];
	inline void add(int x,int y,int v)
	{
		for(int i=x;i<=R;i+=i&(-i))
			for(int j=y;j<=R;j+=j&(-j))
				val[i][j]+=v;
	}
	inline int query(int x,int y)
	{
		int res=0;
		for(int i=x;i>0;i-=i&(-i))
			for(int j=y;j>0;j-=j&(-j))
				res+=val[i][j];
		return res;
	}
}
inline int query(int a,int b,int c,int d)
{
	a=max(a,1),b=min(b,R),c=max(c,1),d=min(d,R);
	if(a>b||c>d)
		return 0;
	return BIT::query(b,d)-BIT::query(a-1,d)-BIT::query(b,c-1)+BIT::query(a-1,c-1);
}
int n,k,q;
inline int calc(int x,int y)
{
	int a1=x-k,b1=x+k,c1=y-k,d1=y+k;
	int res=query(a1,b1,c1,d1);
	int a=(x+y-V-2)>>1,b=x-a-1;
	swap(a,b);
	x=a+b+1,y=a-b+V+1;
	int a2=x-k,b2=x+k,c2=y-k,d2=y+k;
	res+=query(a2,b2,c2,d2);
	res-=query(max(a1,a2),min(b1,b2),max(c1,c2),min(d1,d2));
	return res;
}
long long ans;
inline void calc()
{
	ans=0;
	for(int i=1;i<=n;++i)
		ans+=calc(x[i],y[i]);
}
int main()
{
//	fprintf(stderr,"sizeof(val)=%d\n",(int)sizeof(BIT::val));
//	freopen("input.txt","r",stdin);
//	freopen("output.txt","w",stdout);
	scanf("%d%d%d",&n,&k,&q);
	for(int i=1;i<=n;++i)
	{
		int a,b;
		scanf("%d%d",&a,&b);
		x[i]=a+b+1,y[i]=a-b+V+1;
		BIT::add(x[i],y[i],1);
	}
	calc();
//	fprintf(stderr,"Time: %d ms\n",(int)clock());
	const int lim=2e4;
	while(q--)
	{
//		if(q>1e5-1000)
//			fprintf(stderr,"q=%d\n",q);
		int opt;
		scanf("%d",&opt);
		if(opt==1)
		{
			if(k<=lim)
				printf("%lld\n",(ans-n)>>1);
			else
				printf("%lld\n",n*(n-1ll)>>1);
		}
		else if(opt==2)
		{
			int u;
			scanf("%d",&u);
			if(u==1)
				continue;
			if(k<=lim)
			{
				k*=u;
				if(k<=lim)
					calc();
			}
		}
		else
		{
			int o,a,b;
			scanf("%d%d%d",&o,&a,&b);
			if(k<=lim)
			{
				ans-=calc(x[o],y[o])*2-1;
				BIT::add(x[o],y[o],-1);
				x[o]=a+b+1,y[o]=a-b+V+1;
				BIT::add(x[o],y[o],1);
				ans+=calc(x[o],y[o])*2-1;
			}
		}
	}
	return 0;
}

上一题