题目

描述

有\(n\)只熊,初始时坐标为\((x_i,y_i)\);

这些熊会按照标号依次吼叫,当第\(i\)只熊吼叫,其他熊会移动;

\((x_i,y_i)\)会移动到\((x_i \pm 1,y_i \pm 1)\)离吼叫的熊欧几里得距离最小的位置;

问当第\(i\)只熊生病了,不吼叫也不移动,其他的熊依次吼叫后的\(\sum_{i=1}^{n}x_iy_i\);

依次输出\(ans_i\);

范围

\(2 \le n \le 2.5 \times 10^5 \ , \ 1 \le x_i ,y_i \le 10^6\)

题解

  • $Part  1 $

  • 横纵坐标独立,所以分别考虑每一维的情况;

  • 设将熊按照坐标大小排序并差分,设\(d_i = x_i - x_{i-1},pos_i\)为熊离散后的下标;

  • 那么操作可以看成找到\(pos_i\)之前的第一个不为\(0\)的数字\(--\),找到\(pos_i\)及之后第一个不为\(0\)的数字\(--\);

  • 我们可以找到大家都好好的时候这样子的吼叫区间\((L_i,R_i)\);

  • 容易发现他们是互相包含或者端点相接;

  • 当第\(i\)熊不吼叫时,它减少的贡献初始也是\((L_i,R_i)\),但是 $ i+1 \to m $ 的熊的吼叫区间会影响$ (L_i,R_i) $ ;

  • 可以发现最终\(L_i,R_i\)也是一个区间,只要统计了所有最终这样的区间就可以统计答案;

  • $Part  2 $

  • 考虑第\(j\)只熊吼叫时,​\((L_j,R_j)(j>i)\)依次对​\((L_i,R_i)\)的影响;

    • 当且仅当 $ L_j \le L_i  ,  R_i \le R_j $ 时 $ i $ 会被 $ j $ 影响;
    • 1.若\(R_i<pos_j\),则新的区间为\((L_j,L_i)\);
    • 2.若\(L_i >= pos_j\),则新的区间为\((R_i,R_j)\);
    • 3.若\(L_i<pos_j且pos_j<=R_i\) , 则新的区间为\((L_j,R_j)\);
  • 考虑如何维护这些区间的变化;

  • 由于一次变化后,所有被影响到的区间一定是在左端点或者右端点;

  • 在每个区间的左端点记录\(Right\)集合,对右端点记录\(Left\)集合;

  • 对于在\(pos_i\)左边的区间的\(Left\),显然可以直接加到\(j\)的\(Right\)上;

  • 右边区间的\(Right\)同理;

  • 对于左边区间的\(Right\),可以发现在变化过后所有的区间变成了相同的区间,并查集合并即可

  • 右边区间的\(Left\)和跨越\(pos_i\)的的区间同理;

  • 上述过程可以简单链表+并查集实现,查找包含的区间可以用\(set\)维护;

  • $Part  3 $

  • 考虑如何求最终的答案;

  • 先预处理一个正常情况下的答案;

  • 对于每个熊,设正常情况下最终位置为:\((x_i,y_i)\),相当于变成了\((x_i \pm 1, y_i \pm 1)\);

  • \((x_i+a)(y_i+b) - x_iy_i \ = \ ax_i + by_i + ab\);

  • 前缀和维护\(ax_i\)和\(by_i\)再加个二维数点维护\(ab\)即可;

  • 。。。。。。

    #include<bits/stdc++.h>
    #define ll long long
    #define mk make_pair
    #define fir first
    #define sec second
    using namespace std;
    const int N=1000010;
    int n,px[N],py[N],idx[N],idy[N],dx[N],dy[N],p[N],rk[N];
    int fa[N],pre[N],nxt[N],nt[N],sz,sta[N],top;
    int Lx[N],Rx[N],Ly[N],Ry[N],Lx0[N],Rx0[N],Ly0[N],Ry0[N],tx[N],ty[N],rkx[N],rky[N];
    ll sumx[N],sumy[N],pre_ans;
    inline char gc(){static char*p1,*p2,s[1000000];if(p1==p2)p2=(p1=s)+fread(s,1,1000000,stdin);return(p1==p2)?EOF:*p1++;
    }
    inline int rd(){int x=0;char c=gc();while(c<'0'||c>'9')c=gc();while(c>='0'&&c<='9')x=(x<<1)+(x<<3)+c-'0',c=gc();return x;
    }
    inline bool cmpx(const int&a,const int&b){return px[a]<px[b];}
    inline bool cmpy(const int&a,const int&b){return py[a]<py[b];}
    int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
    int find_nxt(int x){return nxt[x]==x?x:nxt[x]=find_nxt(nxt[x]);}
    int find_pre(int x){return pre[x]==x?x:pre[x]=find_pre(pre[x]);}
    struct table{int hd,tl;};
    void link(table&A,int x){if(!A.hd){nt[A.hd=A.tl=x]=0;return;}nt[A.tl]=x;nt[A.tl=x]=0;
    }
    void link(table&A,table B){if(!B.hd)return;if(!A.hd){A=B;return;}nt[A.tl]=B.hd;A.tl=B.tl;
    }
    struct inter{int l,r;table L,R;void init(const int&id,const int&tl,const int&tr){L.hd=R.hd=L.tl=R.tl=0; l=tl,r=p[id]=tr;
    //        link(L,id);}
    }A[N];
    typedef pair<int,int>pii;
    set<pii>S; set<pii>::iterator st,ed,I;
    void solve(const int*id,int*d,int*L,int*R,int*L0,int*R0){d[0]=d[n]=n+1;for(int i=0;i<=n;++i)pre[i]=nxt[i]=fa[i]=i;for(int i=1;i<n;++i)if(!d[i])pre[i]=i-1,nxt[i]=i+1;for(int i=1;i<=n;++i){int pos=id[i]-1,l=find_pre(pos),r=find_nxt(pos+1),f;L0[i]=l;R0[i]=r;d[l]--;if(!d[l])pre[l]=l-1,nxt[l]=l+1;d[r]--;if(!d[r])pre[r]=r-1,nxt[r]=r+1;A[i].init(i,l,r);st=S.lower_bound(mk(l,0));ed=S.lower_bound(mk(r,0));inter&tmp=A[i];for(I=st;I!=ed;++I){inter now=A[(*I).sec];if(now.r<=pos){if(now.L.hd){p[f=now.L.hd]=now.l;for(int j=nt[f];j;j=nt[j])fa[find(j)]=find(f);link(tmp.L,f);}link(tmp.L,now.R); }else if(now.l>pos){link(tmp.R,now.L);if(now.R.hd){p[f=now.R.hd]=now.r;for(int j=nt[f];j;j=nt[j])fa[find(j)]=find(f);link(tmp.R,f);}}else{int j=now.L.hd;if(j&&p[j]<=pos){p[f=j]=now.l;for(j=nt[f];j&&p[j]<=pos;j=nt[j])fa[find(j)]=find(f);link(tmp.L,f);}for(;j;j=nt[j])fa[find(j)]=find(i);for(j=now.R.hd;j&&p[j]<=pos;j=nt[j])fa[find(j)]=find(i);if(j){p[f=j]=now.r;for(j=nt[f];j;j=nt[j])fa[find(j)]=find(f);link(tmp.R,f);}}}link(tmp.L,i);S.erase(st,ed);S.insert(mk(l,i));}st=S.begin();ed=S.end();for(I=st;I!=ed;++I){inter tmp=A[(*I).sec];for(int j=tmp.L.hd;j;j=nt[j])L[j]=tmp.l,R[j]=p[j];for(int j=tmp.R.hd;j;j=nt[j])R[j]=tmp.r,L[j]=p[j];}S.erase(st,ed);for(int i=1;i<=n;++i)if(find(i)!=i)L[i]=L[fa[i]],R[i]=R[fa[i]];
    }
    struct tree{int sz,rt[N],ls[N*20],rs[N*20],sum[N*20];void insert(int&k,int lst,int l,int r,int x){sum[k=++sz]=sum[lst]+1;ls[k]=ls[lst],rs[k]=rs[lst];if(l==r)return;int mid=l+r>>1;if(x<=mid)insert(ls[k],ls[lst],l,mid,x);else insert(rs[k],rs[lst],mid+1,r,x);}int que(int k,int lst,int l,int r,int x,int y){if(l==x&&r==y)return sum[k]-sum[lst];int mid=l+r>>1;if(y<=mid)return que(ls[k],ls[lst],l,mid,x,y);else if(x>mid)return que(rs[k],rs[lst],mid+1,r,x,y);else return que(ls[k],ls[lst],l,mid,x,mid)+que(rs[k],rs[lst],mid+1,r,mid+1,y);}void insert(int x,int y){insert(rt[x],rt[x-1],1,n,y);}int query(int lx,int rx,int ly,int ry){if(lx>rx||ly>ry)return 0;return que(rt[rx],rt[lx-1],1,n,ly,ry);}
    }T;
    void pre_cal(){for(int i=0;i<=n;++i)dx[i]=dy[i]=0;for(int i=1;i<=n;++i)dx[Rx0[i]+1]--,dy[Lx0[i]]++;for(int i=1;i<=n;++i)dx[i]+=dx[i-1],dy[n-i+1]+=dy[n-i+2];for(int i=1;i<=n;++i)px[idx[i]]+=dx[i]+dy[i];for(int i=0;i<=n;++i)dx[i]=dy[i]=0;for(int i=1;i<=n;++i)dx[Ry0[i]+1]--,dy[Ly0[i]]++;for(int i=1;i<=n;++i)dx[i]+=dx[i-1],dy[n-i+1]+=dy[n-i+2];for(int i=1;i<=n;++i)py[idy[i]]+=dx[i]+dy[i];for(int i=1;i<=n;++i)pre_ans+=1ll*px[i]*py[i];for(int i=1;i<=n;++i)sumx[i]=px[idy[i]]+sumx[i-1],sumy[i]=py[idx[i]]+sumy[i-1];
    }
    ll cal(int id,int lx,int rx,int ly,int ry){ll tmp=pre_ans;tmp-=sumy[lx];tmp+=sumy[n]-sumy[rx];tmp-=sumx[ly];tmp+=sumx[n]-sumx[ry];tmp+=T.query(1,lx,1,ly);tmp-=T.query(1,lx,ry+1,n);tmp-=T.query(rx+1,n,1,ly);tmp+=T.query(rx+1,n,ry+1,n);int fgx=rkx[id]<=lx?-1:rkx[id]>rx?1:0;int fgy=rky[id]<=ly?-1:rky[id]>ry?1:0;tmp-=(ll)(px[id]+fgx)*(py[id]+fgy);tmp+=(ll)tx[id]*ty[id];return tmp;
    }
    int main(){freopen("bear.in","r",stdin);freopen("bear.out","w",stdout);n=rd();for(int i=1;i<=n;++i){tx[i]=px[i]=rd();ty[i]=py[i]=rd();idx[i]=idy[i]=fa[i]=i;}sort(idx+1,idx+n+1,cmpx);sort(idy+1,idy+n+1,cmpy);for(int i=1;i<=n;++i){rkx[idx[i]]=i;rky[idy[i]]=i;dx[i-1]=px[idx[i]]-px[idx[i-1]];dy[i-1]=py[idy[i]]-py[idy[i-1]]; }for(int i=1;i<=n;++i)T.insert(i,rky[idx[i]]);memset(Lx,-1,sizeof(Lx));memset(Rx,-1,sizeof(Rx));memset(Ly,-1,sizeof(Ly));memset(Ry,-1,sizeof(Ry));solve(rkx,dx,Lx,Rx,Lx0,Rx0);solve(rky,dy,Ly,Ry,Ly0,Ry0);pre_cal();for(int i=1;i<=n;++i){ll ans = cal(i,Lx[i],Rx[i],Ly[i],Ry[i]);printf("%lld\n",ans);}return 0;
    }

转载于:https://www.cnblogs.com/Paul-Guderian/p/10617178.html

【纪中集训2019.3.15】恶熊咆哮相关推荐

  1. 【纪中集训2019.3.30】星辰大海

    题目 描述 ​ 有\(n\)个点\(p_1 ,p_2 , \cdots ,\,p_n\) : ​ 现在\(p_1\)不见了,可能的横纵坐标范围是\([-10^6,10^6]\): ​ 同时需要保证每三 ...

  2. 【纪中集训2019.3.25】芬威克树

    题目 描述 ​ ​ 第一段代码正确第用\(k\)进制\(BIT\)维护了前缀和: ​ 第二段代码由于写错了\(line \ 4\),所以意义发生了改变: ​ 维护第二段代码执行\(ADD(x,v)\) ...

  3. 【纪中集训2019.3.12】Mas的仙人掌

    题意: ​ 给出一棵\(n\)个点的树,需要加\(m\)条边,每条边脱落的概率为\(p_{i}\) ,求加入的边在最后形成图中仅在一个简单环上的边数的期望: \(1 \le n \ , m \le 1 ...

  4. 【纪中集训2019.3.20】铁路

    题意 描述 现在有一颗树形状的双向铁路,每条边的行驶时间是\(1\): 给出\(m\)条列车行驶的路径\(s_{i}\to t_{i}\),问列车相遇的对数(无序对): \(i和j\)号列车相遇当且仅 ...

  5. 【纪中集训2019.3.26】动态半平面交

    题目 描述 : 给出强制在线参数\(k\),树的大小\(n\),和每个点的点权\(a_i\); 有\(m\)个询问,每个询问是$u ,d $ 的形式: 表示询问\(u\)为根的子树中,和\(u\)的距 ...

  6. 2019寒假纪中集训总结学期总结(流水账)

    学期总结 这学期上了初三,学校的初.高中校区对调,我们的班主任也由一个生物老师换成了一个化学老师. 之前的班主任比较年轻,跟我们这群学生有这很好的感情,亦师亦友,陪伴我们度过了几乎没有中考压力的初一. ...

  7. [2021.8纪中集训Day14]

    文章目录 1312. 老曹的忧郁 题目 思路 代码 1313. 老曹骑士 题目 思路 代码 1314. 稳定的数字 题目 思路 代码 封锁阳光大学 题目 题目描述 输入格式 输出格式 输入输出样例 说 ...

  8. 纪中集训2020.01.13【NOIP普及组】模拟赛C组总结————My First Time Write Summary

    纪中集训2020.01.13[NOIP普及组]模拟赛C组总结 题目编号 标题 0 [NOIP普及组模拟]取值( numbers.pas/cpp) 1 [NOIP普及组模拟]数对(pairs.pas/c ...

  9. 纪中集训2020.01.16【NOIP普及组】模拟赛C组总结+【0.Matrix】分析

    纪中集训2020.01.16[NOIP普及组]模拟赛C组总结+[0.Matrix]分析 题目: 0.matrix 1.product 2.binary 3.value 巨佬估分:100+100+40+ ...

最新文章

  1. Windows Phone 7、XNA的旋转的背景
  2. numpy 若干行和列_Numpy的轴,pandas的行和列
  3. 利用Certbot工具快速给网站部署Let's Encrypt免费SSL证书
  4. c 结构体在声明时赋值_C/C++编程笔记:C++入门知识,C++多态性和虚函数解析
  5. UnrealEngine4 - 关于UObject被自动GC垃圾回收的巨坑
  6. 李维说他跳槽了,那我以后也不是Borland的Fans了?
  7. EasyUI的简单介绍
  8. ll按时间排序和查看目录下文件数
  9. 人脸关键点: Wing Loss for Robust Facial Landmark Localisation with Convolutional Neural Networks
  10. KindEditor - 代码高亮
  11. malloc和new的区别和联系
  12. ubuntu环境下如何设置开机启动项
  13. 蓝牙音乐之AVRCP常用指令介绍
  14. Html的基本操作简介
  15. 如何使用Arduino和R305制作指纹考勤系统
  16. 神经网络的起源和发展,神经网络的网络结构
  17. 手机搭建php环境,安卓手机搭建PHP环境教程
  18. 蓝牙耳机什么牌子好?安卓蓝牙耳机性价比推荐
  19. java判断硬盘为固态硬盘_怎么看电脑是不是固态硬盘|查询电脑硬盘是HDD还是SSD的方法-系统城...
  20. ensp防火墙出口路由双链路运营商,负载分担及设备冗余

热门文章

  1. Win7实现快速启动栏并实现靠左边的终极操作方法(已解决)!
  2. linux批量重命名后缀名,Linux 批量重命名文件的方法
  3. 2014校园招聘总结(转载)
  4. 「镁客早报」库克抨击高通,表明不可能在法律纠纷中达成和解;传闻无人驾驶公司Aurora融资20亿美元...
  5. java 下载样板Excel文件
  6. ゃōゃ♥ ♡๑۩ﺴ ☜ ☞ 一些小符号
  7. C11简洁之道:tupe元祖
  8. 我在做开源芯片 | 人物志
  9. swf无法在html播放器,错误? FlashPlayer 10根据SWF/HTML播放器设置,投影机无法进入全屏...
  10. 2019我干了什么!2020我该干些什么?