icpc2019 南京网络赛选拔赛 A 二维数点+蛇形填数
做法:
把每次询问按容斥定理分成四个二维前缀和查询,然后对x排序,扫描线即可
#pragma GCC optimize("Ofast")
#include<bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define fi first
#define se second
#define mp make_pair
#define pii pair<ll,ll>
#define all(x) x.begin(),x.end()
#define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define rep(ii,a,b) for(int ii=a;ii<=b;++ii)
#define per(ii,a,b) for(int ii=b;ii>=a;--ii)
#define forn(i,x,g,e) for(int i=g[x];i;i=e[i].next)
#define show(x) cout<<#x<<"="<<x<<endl
#define showa(a,b) cout<<#a<<'['<<b<<"]="<<a[b]<<endl
#define show2(x,y) cout<<#x<<"="<<x<<" "<<#y<<"="<<y<<endl
#define show3(x,y,z) cout<<#x<<"="<<x<<" "<<#y<<"="<<y<<" "<<#z<<"="<<z<<endl
#define show4(w,x,y,z) cout<<#w<<"="<<w<<" "<<#x<<"="<<x<<" "<<#y<<"="<<y<<" "<<#z<<"="<<z<<endl
#define show5(v,w,x,y,z) cout<<#v<<"="<<v<<" "<<#w<<"="<<w<<" "<<#x<<"="<<x<<" "<<#y<<"="<<y<<" "<<#z<<"="<<z<<endl
#define showmm(x,a,b) rep(i,0,a) rep(j,0,b) cout<<#x<<'['<<i<<']'<<'['<<j<<"]="<<x[i][j]<<(" \n"[j==b])
#define showm(x,a,b) rep(i,0,a) rep(j,0,b) cout<<x[i][j]<<(" \n"[j==b])
#define showa1(x,a,b) cout<<#x<<":\n";rep(i,a,b) showa(x,i);cout<<endl
#define showa2(x,a,b) cout<<#x<<": ";rep(i,a,b) cout<<x[i]<<' ';cout<<endl
using namespace std;//head
const int maxn=1e6+10,maxm=2e6+10;
const ll INF=0x3f3f3f3f,mod=1e9+7;
int casn,n,m,k,num[maxn];
namespace fastio{//@支持读取整数,字符串,输出整数@
bool isdigit(char c){return c >= 48 && c <= 57;}
const int maxsz=1e7;
class fast_iostream{public:
char ch=get_char();
bool endf=1,flag;
char get_char(){
static char buffer[maxsz],*a=buffer,*b=buffer;
return b==a&&(b=(a=buffer)+fread(buffer,1,maxsz, stdin),b==a)?EOF:*a++;
}
template<typename type>bool get_int(type& tmp){
flag=tmp=0;
while(!isdigit(ch)&&ch!=EOF){flag=ch=='-';ch=get_char();};
if(ch==EOF)return endf=0;
do{tmp=ch-48+tmp*10;}while(isdigit(ch=get_char()));
if(flag)tmp=-tmp;
return 1;
}
int get_str(char* str){
char* tmp=str;
while(ch=='\r'||ch=='\n'||ch==' ')ch=get_char();
if(ch==EOF)return(endf=0),*tmp=0;
do{*(tmp++)=ch;ch=get_char();}while(ch!='\r'&&ch!='\n'&&ch!=' '&&ch!=EOF);
*(tmp++)=0;
return(int)(tmp-str-1);
}
fast_iostream& operator>>(char* tmp){get_str(tmp);return *this;}
template<typename type>fast_iostream& operator>>(type& tmp){get_int(tmp);return *this;}
operator bool() const {return endf;}
};
}
fastio::fast_iostream io;
int a[maxn];
struct bit{
ll node[maxn],n;
inline int lb(int x) {return x&(-x);}
void init(int _n){n=_n;fill_n(node,n+2,0);}
inline void update(int pos,ll val){
if(pos>0)for(int i=pos;i<=n;i+=lb(i))
node[i]+=val;
}
inline ll ask(int pos){
ll sum=0;
if(pos>0)for(int i=pos;i;i-=lb(i))
sum+=node[i];
return sum;
}
inline ll query(int l,int r){
return ask(r)-ask(l-1);
}
}tree;
struct node{int x,y,id;ll val;}point[maxn],ask[maxn];
int cmp(node a,node b){
if(a.x==b.x) return a.y<b.y;
return a.x<b.x;
}
ll ans[maxn];
ll getv(int x,int y){
x-=n/2+1;y-=n/2+1;
ll tmp=max(abs(x),abs(y));
if(x>=y) return 1ll*n*n-4*tmp*tmp-2*tmp-x-y;
else return 1ll*n*n-4*tmp*tmp+2*tmp+x+y;
}
int cal(ll v){
ll ans=0;
while(v){ans+=v%10;v/=10;}
return ans;
}
int main() {
io>>casn;
while(casn--){
io>>n>>k>>m;
int cnt=0;
rep(i,1,k){
io>>point[i].x>>point[i].y;
point[i].id=i;
point[i].val=cal(getv(point[i].x,point[i].y));
}
sort(point+1,point+1+k,cmp);
rep(i,1,m){
ans[i]=0;
int a,b,c,d;
io>>a>>b>>c>>d;
ask[++cnt]={c,d,i,1};
ask[++cnt]={a-1,d,i,-1};
ask[++cnt]={c,b-1,i,-1};
ask[++cnt]={a-1,b-1,i,1};
}
sort(ask+1,ask+1+cnt,cmp);
int l=1;
tree.init(n+1);
rep(i,1,cnt){
while(l<=k&&point[l].x<=ask[i].x){
tree.update(point[l].y,point[l].val);
l++;
}
int id=ask[i].id;
ans[id]+=ask[i].val*tree.query(1,ask[i].y);
}
rep(i,1,m) printf("%lld\n",ans[i]);
}
return 0;
}

浙公网安备 33010602011771号