zoukankan      html  css  js  c++  java
  • POI2018

    [BZOJ5099][POI2018]Pionek(极角排序+two pointers)

    几个不会严谨证明的结论:

    1.将所有向量按极角排序,则答案集合一定是连续的一段。

    当答案方向确定时,则一个向量会被选入答案集合当且仅当向量在答案方向上的投影一定都是正的

    所以,两个选中向量中间隔着一个向量,则必然可以将后面所有选中向量均前移一位并使答案不劣。

    2.答案集合中不存在两个向量的极角差超过$pi$

    显然需要保证的是,答案集合中任意两个向量投影不为负值,否则一定可以通过删去其中一个使答案更优。

    3.当选择的向量集合区间左端点增加时,右端点单调不减。

    感性理解,答案向量的极角会在选择的向量区间中某两个相邻向量极角之间。当区间左端点增加时,答案向量的极角必然增加,故右端点不会减少。

    于是,将所有向量极角排序后,对所有扫过的极角极差不超过$pi$的向量区间更新答案即可。

     1 #include<cmath>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #define rep(i,l,r) for (int i=(l); i<=(r); i++)
     5 typedef long long ll;
     6 using namespace std;
     7 
     8 const int N=400010;
     9 const double pi=acos(-1.);
    10 int n;
    11 ll ans;
    12 struct P{
    13     int x,y; double s;
    14     bool operator <(const P &a)const{ return s<a.s; }
    15     P operator +(const P &a)const{ return (P){x+a.x,y+a.y}; }
    16     P operator -(const P &a)const{ return (P){x-a.x,y-a.y}; }
    17     ll len(){ return 1ll*x*x+1ll*y*y; }
    18 }a[N];
    19 
    20 int main(){
    21     freopen("bzoj5099.in","r",stdin);
    22     freopen("bzoj5099.out","w",stdout);
    23     scanf("%d",&n);
    24     rep(i,1,n) scanf("%d%d",&a[i].x,&a[i].y),a[i].s=atan2(a[i].x,a[i].y);
    25     sort(a+1,a+n+1); P cur=(P){0,0}; int x=0;
    26     rep(i,1,n) a[i+n]=a[i],a[i+n].s+=2*pi;
    27     rep(i,1,n){
    28         while (x<n*2 && a[x+1].s-a[i].s<=pi) cur=cur+a[++x],ans=max(ans,cur.len());
    29         cur=cur-a[i]; ans=max(ans,cur.len());
    30     }
    31     printf("%lld
    ",ans);
    32     return 0;
    33 }

    [BZOJ5100][POI2018]Plan metra(构造)

    若1与n直接相连,则所有点到1与n的距离差的绝对值是相同的,根据距离选择与1还是n直接相连即可。

    若不直接相连,则其余所有点到1与n的距离和的最小值就是1到n的距离。

    找到所有在1到n的路径上的点,按与1的距离排序,然后相邻的两两连边。其余点算出应该挂在链上哪个点下面,注意判断各种不合法即可。

     1 #include<cstdio>
     2 #include<algorithm>
     3 #define rep(i,l,r) for (int i=(l); i<=(r); i++)
     4 typedef long long ll;
     5 using namespace std;
     6 
     7 const int N=1000010;
     8 int n,a[N],b[N],id[N];
     9 struct P{ int x,i; }d[N];
    10 bool operator <(const P &a,const P &b){ return a.x<b.x; }
    11 
    12 int main(){
    13     freopen("bzoj5100.in","r",stdin);
    14     freopen("bzoj5100.out","w",stdout);
    15     scanf("%d",&n);
    16     rep(i,2,n-1) scanf("%d",&a[i]);
    17     rep(i,2,n-1) scanf("%d",&b[i]);
    18     if (n==2){ printf("TAK
    1 2 1
    "); return 0; }
    19     int len=abs(a[2]-b[2]);
    20     rep(i,3,n-1) if (abs(a[i]-b[i])!=len){ len=0; break; }
    21     if (len){
    22         puts("TAK"); printf("1 %d %d
    ",n,len);
    23         rep(i,2,n-1)
    24             if (a[i]>b[i]) printf("%d %d %d
    ",i,n,b[i]);
    25                 else printf("%d %d %d
    ",i,1,a[i]);
    26         return 0;
    27     }
    28     len=2000000; int tot=0;
    29     rep(i,2,n-1) len=min(len,a[i]+b[i]);
    30     rep(i,2,n) if (a[i]+b[i]==len) d[++tot]=(P){a[i],i};
    31     sort(d+1,d+tot+1); d[0]=(P){0,1}; d[++tot]=(P){len,n};
    32     rep(i,1,tot) if (d[i].x==d[i-1].x){ puts("NIE"); return 0; }
    33     rep(i,0,tot) id[d[i].x]=d[i].i;
    34     rep(i,2,n-1) if (a[i]+b[i]>len && (((a[i]+b[i]-len)&1) || !id[a[i]-(a[i]+b[i]-len)/2])){ puts("NIE"); return 0; }
    35     puts("TAK");
    36     rep(i,1,tot) printf("%d %d %d
    ",d[i-1].i,d[i].i,d[i].x-d[i-1].x);
    37     rep(i,2,n-1) if (a[i]+b[i]>len) printf("%d %d %d
    ",id[a[i]-(a[i]+b[i]-len)/2],i,(a[i]+b[i]-len)/2);
    38     return 0;
    39 }

     [BZOJ5101][POI2018]Powódź(并查集)

    类似于Kruskal重构树上DP。

    相邻点之间连一条权为墙高的边,将边从小到大排序,每次合并一条边连接的两个连通块。

    h[i]表示连通块i中最高的墙,g[i]表示所有水位都不超过h[i]的情况下的方案数。最后答案就是g[1]+H-h[1]。

    当某处水位高于h[i]时,水就会往四周流淌,所以合并边权为w的边连接的两个连通块时,h=w,g=(g1+w-h1)*(g2+w-h2)。

    意思就是,新的方案数,等于两个连通块在水位均不超过w时的方案数之积。一个连通块水位不超过w的方案数,等于水位不超过h1的方案数,加所有区域水位相等且都大于h1的方案数,即g1+w-h1。

     1 #include<cstdio>
     2 #include<algorithm>
     3 #define F(A,B) ((A-1)*m+B)
     4 #define rep(i,l,r) for (int i=(l); i<=(r); i++)
     5 typedef long long ll;
     6 using namespace std;
     7 
     8 const int N=500010,mod=1000000007;
     9 int n,m,H,x,tot,f[N],g[N],h[N];
    10 struct E{ int u,v,w; }e[N<<1];
    11 bool operator <(const E &a,const E &b){ return a.w<b.w; }
    12 int get(int x){ return (f[x]==x) ? x : f[x]=get(f[x]); }
    13 
    14 int main(){
    15     freopen("bzoj5101.in","r",stdin);
    16     freopen("bzoj5101.out","w",stdout);
    17     scanf("%d%d%d",&n,&m,&H);
    18     rep(i,1,n) rep(j,1,m-1) scanf("%d",&x),e[++tot]=(E){F(i,j),F(i,j+1),x};
    19     rep(i,1,n-1) rep(j,1,m) scanf("%d",&x),e[++tot]=(E){F(i,j),F(i+1,j),x};
    20     sort(e+1,e+tot+1);
    21     rep(i,1,n*m) f[i]=i,g[i]=1,h[i]=0;
    22     rep(i,1,tot){
    23         int x=get(e[i].u),y=get(e[i].v);
    24         if (x==y) continue;
    25         g[y]=1ll*(g[x]+e[i].w-h[x])*(g[y]+e[i].w-h[y])%mod;
    26         h[y]=e[i].w; f[x]=y;
    27     }
    28     printf("%d
    ",(g[get(1)]+H-h[get(1)])%mod);
    29     return 0;
    30 }

    [BZOJ5102][POI2018]Prawnicy(堆)

    区间排序后堆维护前k大,据说其它数据结构都被卡常了。

     1 #include<queue>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #define rep(i,l,r) for (int i=(l); i<=(r); i++)
     5 typedef long long ll;
     6 using namespace std;
     7 
     8 const int N=1000010;
     9 int n,m,ans,u,v;
    10 struct P{ int l,r,id; }a[N];
    11 bool operator <(const P &a,const P &b){ return a.r<b.r; }
    12 priority_queue<int>Q;
    13 
    14 int main(){
    15     freopen("bzoj5102.in","r",stdin);
    16     freopen("bzoj5102.out","w",stdout);
    17     scanf("%d%d",&n,&m);
    18     rep(i,1,n) scanf("%d%d",&a[i].l,&a[i].r),a[i].id=i;
    19     sort(a+1,a+n+1);
    20     for (int i=n; i; i--){
    21         Q.push(a[i].l);
    22         if (n-i+1>=m){
    23             int x=Q.top(); Q.pop();
    24             if (a[i].r-x>ans) u=x,v=i,ans=a[i].r-x;
    25         }
    26     }
    27     printf("%d
    ",ans);
    28     rep(i,v,n) if (a[i].l<=u) printf("%d ",a[i].id);
    29     return 0;
    30 }
  • 相关阅读:
    elemen-ui表格多选,分页保持勾选状态的实现
    element-ui中的change事件传递多个参数的方法
    vue中访问不存在路由默认跳转404页面实现方法
    IntelliJ IDEA 汉化包
    vue 移动端项目用手机预览调试
    vue 中使用 rem
    vue中配置axios.js文件,发送请求
    vue中axios的使用
    爬楼梯
    不同路径
  • 原文地址:https://www.cnblogs.com/HocRiser/p/10260130.html
Copyright © 2011-2022 走看看