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

 

posted @ 2019-09-03 15:09  nervending  阅读(185)  评论(0编辑  收藏  举报