• Petrozavodsk Summer-2016. Ural FU Dandelion Contest


    A. Square Function

    留坑。

    B. Guess by Remainder

    询问$lcm(1,2,3,...,n)-1$即可一步猜出数。

    计算$lcm$采用分治FFT即可,时间复杂度$O(nlog^2n)$。

    C. Subtract if Greater!

    对于每个修改操作,$[1,x]$的数无需修改,$[x+1,2x]$的数会减小至少一半,暴力修改即可,$[2x+1,inf]$的数减小之后排名不变,故可以在平衡树上打标记实现。

    时间复杂度$O(nlog^2n+mlog n)$。

    #include<cstdio>
    #include<algorithm>
    const int N=100010,inf=~0U>>1;
    int n,m,i,op,k,a[N],val[N],tag[N],size[N],son[N][2],f[N],tot,root;
    inline void read(int&a){char c;while(!(((c=getchar())>='0')&&(c<='9')));a=c-'0';while(((c=getchar())>='0')&&(c<='9'))(a*=10)+=c-'0';}
    inline void add1(int x,int p){
      if(!x)return;
      val[x]+=p;
      tag[x]+=p;
    }
    inline void pb(int x){
      if(tag[x]){
        add1(son[x][0],tag[x]);
        add1(son[x][1],tag[x]);
        tag[x]=0;
      }
    }
    inline void up(int x){
      size[x]=1;
      if(son[x][0])size[x]+=size[son[x][0]];
      if(son[x][1])size[x]+=size[son[x][1]];
    }
    inline void rotate(int x){
      int y=f[x],w=son[y][1]==x;
      son[y][w]=son[x][w^1];
      if(son[x][w^1])f[son[x][w^1]]=y;
      if(f[y]){
        int z=f[y];
        if(son[z][0]==y)son[z][0]=x;
        if(son[z][1]==y)son[z][1]=x;
      }
      f[x]=f[y];son[x][w^1]=y;f[y]=x;up(y);
    }
    inline void splay(int x,int w){
      int s=1,i=x,y;a[1]=x;
      while(f[i])a[++s]=i=f[i];
      while(s)pb(a[s--]);
      while(f[x]!=w){
        y=f[x];
        if(f[y]!=w){if((son[f[y]][0]==y)^(son[y][0]==x))rotate(x);else rotate(y);}
        rotate(x);
      }
      if(!w)root=x;
      up(x);
    }
    int build(int l,int r,int fa){
      int x=++tot,mid=(l+r)>>1;
      f[x]=fa;val[x]=a[mid];
      if(l<mid)son[x][0]=build(l,mid-1,x);
      if(r>mid)son[x][1]=build(mid+1,r,x);
      up(x);
      return x;
    }
    inline void ask(int k){
      int x=root,t;
      while(x){
        pb(x);
        if(val[x]>k)t=x,x=son[x][0];else x=son[x][1];
      }
      splay(t,0);
    }
    void ins(int&x,int y,int fa){
      if(!x){
        x=y;
        f[y]=fa;
        return;
      }
      pb(x);
      size[x]++;
      if(val[y]<val[x])ins(son[x][0],y,x);else ins(son[x][1],y,x);
    }
    inline void change(int k){
      while(1){
        ask(k);
        int x=root;
        if(val[x]<=k*2){
          int y=son[x][1];
          while(son[y][0])y=son[y][0];
          splay(y,x);
          son[y][0]=son[x][0];
          f[y]=0;
          f[son[x][0]]=y;
          up(root=y);
          val[x]-=k;
          tag[x]=0;
          son[x][0]=son[x][1]=0;
          size[x]=1;
          ins(root,x,0);
          splay(x,0);
        }else{
          val[x]-=k;
          add1(son[x][1],-k);
          while(son[x][1])x=son[x][1];
          val[x]=inf;
          splay(x,0);
          return;
        }
      }
    }
    inline int kth(int k){
      int x=root,tmp;
      while(1){
        pb(x);
        tmp=size[son[x][0]]+1;
        if(k==tmp){
          splay(x,0);
          return val[x];
        }
        if(k<tmp)x=son[x][0];else k-=tmp,x=son[x][1];
      }
    }
    int main(){
      read(n),read(m);
      for(i=1;i<=n;i++)read(a[i]);
      a[++n]=0;
      a[++n]=inf;
      std::sort(a+1,a+n+1);
      root=build(1,n,0);
      while(m--){
        read(op),read(k);
        if(op==2)change(k);else printf("%d
    ",kth(k+1));
      }
      return 0;
    }
    

      

    D. Eastern Subregional

    留坑。

    E. K-transform

    DP显然,快速幂+FFT优化即可。时间复杂度$O(klog klog m)$。

    F. Suffix Array for Thue-Morse

    留坑。

    G. XOR Tree

    求出路径上偶数的集合然后分类讨论即可。

    #include <bits/stdc++.h>
    using namespace std ;
    
    typedef long long LL ;
    
    const int MAXN = 100005 ;
    const int MAXE = 200005 ;
    
    struct Edge {
        int v , n ;
        Edge () {}
        Edge ( int v , int n ) : v ( v ) , n ( n ) {}
    } ;
    
    Edge E[MAXE] ;
    int H[MAXN] , cntE ;
    int dep[MAXN] ;
    int top[MAXN] ;
    int siz[MAXN] ;
    int son[MAXN] ;
    int pre[MAXN] ;
    int pos[MAXN] ;
    LL val[MAXN] ;
    LL sum[MAXN] ;
    int precol[MAXN] ;
    int even[MAXN] ;
    int tree_idx ;
    int n , q ;
    int eu[MAXN] , ev[MAXN] , ec[MAXN] ;
    vector < int > G ;
    LL all ;
    
    void init () {
        cntE = 0 ;
        tree_idx = 0 ;
        memset ( H , -1 , sizeof H ) ;
        memset ( val , 0 , sizeof val ) ;
        memset ( sum , 0 , sizeof sum ) ;
        memset ( even , 0 , sizeof even ) ;
    }
    
    void addedge ( int u , int v ) {
        E[cntE] = Edge ( v , H[u] ) ;
        H[u] = cntE ++ ;
    }
    
    void dfs ( int u ) {
        son[u] = 0 ;
        siz[u] = 1 ;
        for ( int i = H[u] ; ~i ; i = E[i].n ) {
            int v = E[i].v ;
            if ( v == pre[u] ) continue ;
            dep[v] = dep[u] + 1 ;
            pre[v] = u ;
            dfs ( v ) ;
            siz[u] += siz[v] ;
            if ( siz[son[u]] < siz[v] ) son[u] = v ;
        }
    }
    
    void rebuild ( int u , int top_element ) {
        top[u] = top_element ;
        pos[u] = ++ tree_idx ;
        if ( son[u] ) rebuild ( son[u] , top_element ) ;
        for ( int i = H[u] ; ~i ; i = E[i].n ) {
            int v = E[i].v ;
            if ( v == pre[u] || v == son[u] ) continue ;
            rebuild ( v , v ) ;
        }
    }
    
    void dfs2 ( int u , int it ) {
        precol[u] = it ;
        for ( int i = H[u] ; ~i ; i = E[i].n ) {
            int v = E[i].v ;
            if ( v == pre[u] ) continue ;
            dfs2 ( v , val[u] % 2 ? it : u ) ;
        }
    }
    
    void geteven ( int u , int lca ) {
      //printf("geteven %d %d
    ",u,lca);
        while ( dep[u] > dep[lca] ) {
          //printf("  %d %d %d
    ",u,val[u],precol[u]);
            if ( val[u] % 2 == 0 ) {
              G.push_back ( val[u] ) ;
            }
            u = precol[u] ;
        }
    }
    
    void deal ( int u , int v ) {
        LL tot = 0 , num = 0 ;
        int x = u , y = v ;
        //return;
        while ( top[u] != top[v] ) {
            if ( dep[top[u]] < dep[top[v]] ) swap ( u , v ) ;
            num += even[pos[u]] - even[pos[top[u]] - 1] ;
            tot += sum[pos[u]] - sum[pos[top[u]] - 1] ;
            u = pre[top[u]] ;
        }
        //return;
        if ( dep[u] > dep[v] ) swap ( u , v ) ;
        num += even[pos[v]] - even[pos[u]] ;
        tot += sum[pos[v]] - sum[pos[u]] ;
        if ( num == 0 ) {
            printf ( "1
    " ) ;
            return ;
        }
        if ( num >= 3 ) {
            printf ( "2
    " ) ;
            return ;
        }
        G.clear () ;
        geteven ( x , u ) ;
        geteven ( y , u ) ;
        int dis = dep[x] + dep[y] - 2 * dep[u] ;
        sort ( G.begin () , G.end () ) ;
        dis -= ( int ) G.size () ;
        int out = ( all - tot ) & 1 ;
        
        
       // printf("->%d
    ",G.size());
        //return;
        
        if ( num == 1 ) {
            if ( G[0] >= dis ) {
                printf ( "1
    " ) ;
                return ;
            } else {
                printf ( "2
    " ) ;
                return ;
            }
        }
        //return;
        if ( num == 2 ) {
            G[0] -= dis - 1 ;
            if ( G[0] <= 1 ) {
                printf ( "2
    " ) ;
                return ;
            } else {
                G[0] %= 2 ;
                if ( ( G[0] == 0 ) ^ ( out == 0 ) ) printf ( "2
    " ) ;
                else printf ( "1
    " ) ;
                return ;
            }
        }
    }
    
    void solve () {
        init () ;
        all = 0 ;
        for ( int i = 1 ; i < n ; ++ i ) {
            scanf ( "%d%d%d" , &eu[i] , &ev[i] , &ec[i] ) ;
            addedge ( eu[i] , ev[i] ) ;
            addedge ( ev[i] , eu[i] ) ;
            all += ec[i] ;
        }
        dfs ( 1 ) ;
        rebuild ( 1 , 1 ) ;
        for ( int i = 1 ; i < n ; ++ i ) {
            if ( dep[eu[i]] > dep[ev[i]] ) {
                sum[pos[eu[i]]] = ec[i] ;
                val[eu[i]] = ec[i] ;
                even[pos[eu[i]]] = ec[i] % 2 == 0 ;
            } else {
                sum[pos[ev[i]]] = ec[i] ;
                val[ev[i]] = ec[i] ;
                even[pos[ev[i]]] = ec[i] % 2 == 0 ;
            }
        }
        dfs2 ( 1 , 0 ) ;
        for ( int i = 2 ; i <= n ; ++ i ) {
            sum[i] += sum[i - 1] ;
            even[i] += even[i - 1] ;
        }
        while ( q -- ) {
            int u , v ;
            scanf ( "%d%d" , &u , &v ) ;
            deal ( u , v ) ;
        }
    }
    
    int main () {
        while ( ~scanf ( "%d%d" , &n , &q ) ) solve () ;
        return 0 ;
    }
    

      

    H. Fence

    留坑。

    I. Friends and Berries - 2

    首先求出凸包,然后分治求出每个点的最远点,检查一下直径是否合法,是的话那么所有直径都是答案。时间复杂度$O(nlog n)$。

    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    #include<vector>
    #include<map>
    #include<set>
    using namespace std;
    typedef long long ll;
    typedef pair<int,int>PI;
    const int N=500010;
    int n,i,f[N];ll d[N];
    map<PI,int>idx;
    set<PI>ans;
    struct P{
      int x,y;
      P(){x=y=0;}
      P(int _x,int _y){x=_x,y=_y;}
      void input(){scanf("%d%d",&x,&y);}
      bool operator<(const P&p)const{
        if(x!=p.x)return x<p.x;
        return y<p.y;
      }
    }a[N],b[N];
    inline ll dis(const P&a,const P&b){
      return 1LL*(a.x-b.x)*(a.x-b.x)+1LL*(a.y-b.y)*(a.y-b.y);
    }
    inline ll cal(int x,int y){
      ll t=dis(b[x],b[y]);
      if(y<x||y>=x+n)return -t;
      return t;
    }
    inline ll vect(P p,P p1,P p2){
      return 1LL*(p1.x-p.x)*(p2.y-p.y)-1LL*(p1.y-p.y)*(p2.x-p.x);
    }
    int convexhull(P*p,int n,P*q){
      int i,k,m;
      sort(p,p+n);
      m=0;
      for(i=0;i<n;q[m++]=p[i++])while(m>1&&vect(q[m-2],q[m-1],p[i])<0)m--;
      k=m;
      for(i=n-2;i>=0;q[m++]=p[i--])while(m>k&&vect(q[m-2],q[m-1],p[i])<0)m--;
      return --m;
    }
    void solve(int l,int r,int dl,int dr){
      int m=(l+r)>>1;
      f[m]=dl;
      d[m]=cal(m,dl);
      for(int i=dl+1;i<=dr;i++){
        ll t=cal(m,i);
        if(t>d[m])d[m]=t,f[m]=i;
      }
      if(l<m)solve(l,m-1,dl,f[m]);
      if(r>m)solve(m+1,r,f[m],dr);
    }
    inline bool check(P A,P B){
      for(int i=0;i<n;i++)if(dis(A,B)<dis(A,b[i])+dis(B,b[i]))return 0;
      return 1;
    }
    inline void newans(int x,int y){
      if(x==y)return;
      if(x>y)swap(x,y);
      ans.insert(PI(x,y));
    }
    int main(){
      scanf("%d",&n);
      for(i=0;i<n;i++){
        a[i].input();
        idx[PI(a[i].x,a[i].y)]=i+1;
      }
      n=convexhull(a,n,b);
      if(n==2){
        for(i=0;i<n;i++)printf("%d ",idx[PI(b[i].x,b[i].y)]);
        return 0;
      }
      for(i=0;i<n;i++)b[i+n]=b[i];
      solve(0,n-1,0,n*2-1);
      int x=0;
      for(i=1;i<n;i++)if(d[i]>d[x])x=i;
      for(i=0;i<n;i++)f[i]%=n;
      if(!check(b[x],b[f[x]]))return puts("0"),0;
      for(i=0;i<n;i++)if(d[i]==d[x]){
            //if(!check(b[i],b[f[i]))while(1);
            newans(i,f[i]);
      }
      //for(i=0;i<n;i++)printf("%d %d
    ",b[i].x,b[i].y);
      //puts("");
      printf("%d
    ",ans.size());
      for(set<PI>::iterator it=ans.begin();it!=ans.end();it++){
        //printf("%d %d
    ",it->first,it->second);
        printf("%d %d
    ",idx[PI(b[it->first].x,b[it->first].y)],
                         idx[PI(b[it->second].x,b[it->second].y)]);
      }
    }
    

      

    J. Oleg and Cola

    超图上的最短路,dijkstra+染色即可。时间复杂度$O(mlog m)$。

    #include<cstdio>
    #include<queue>
    #include<vector>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    typedef pair<int,int>P;
    typedef pair<ll,P>PI;
    const int N=200010;
    int n,m,i,ce,id[N],st[N][2],en[N][2];
    int cnt,fin[N*2];
    P pos;ll ans;
    bool v[N][2];
    ll d[N][2];
    P pre[N][2];
    priority_queue<PI,vector<PI>,greater<PI> >q;
    struct E{
      int u,v,len,light;
      E(){}
      E(int _u,int _v,int _len,int _light){u=_u,v=_v,len=_len,light=_light;}
    }e[N];
    inline bool cmp(int x,int y){
      if(e[x].u!=e[y].u)return e[x].u<e[y].u;
      return e[x].light<e[y].light;
    }
    inline void ext(int x,int y,ll z,P p){
      if(v[x][y])return;
      z+=e[x].len;
      v[x][y]=1;
      d[x][y]=z;
      pre[x][y]=p;
      q.push(PI(z,P(x,y)));
    }
    int main(){
      scanf("%d%d",&n,&m);
      for(ce=i=1;i<=m;i++){
        int u,v,len,light;
        scanf("%d%d%d%d",&u,&v,&len,&light);
        e[++ce]=E(u,v,len,light);
        e[++ce]=E(v,u,len,light);
      }
      for(i=2;i<=ce;i++)id[i]=i;
      sort(id+2,id+ce+1,cmp);
      for(i=1;i<=n;i++)st[i][0]=1;
      for(i=2;i<=ce;i++)en[e[id[i]].u][0]=i;
      for(i=ce;i>1;i--)st[e[id[i]].u][0]=i;
      for(i=1;i<=n;i++)st[i][1]=st[i][0],en[i][1]=en[i][0];
      for(i=2;i<=ce;i++)if(e[i].u==1)ext(i,0,0,P(0,0));
      while(!q.empty()){
        PI t=q.top();q.pop();
        int x=t.second.first,y=t.second.second;
        ll z=t.first;
        int o=e[x].v;
        while(st[o][y]<=en[o][y]){
          int i=id[en[o][y]];
          if(e[i].light<e[x].light)break;
          ext(i,y,z,P(x,y));
          en[o][y]--;
        }
        if(o==2&&y==0){
          while(st[o][1]<=en[o][1]){
            int i=id[en[o][1]];
            if(e[i].light<e[x].light)break;
            ext(i,1,z,P(x,y));
            en[o][1]--;
          }
        }
      }
      ans=1LL<<60;
      for(i=2;i<=ce;i++)if(e[i].v==1&&v[i][1]){
        if(d[i][1]<ans){
          ans=d[i][1];
          pos=P(i,1);
        }
      }
      printf("%lld
    ",ans);
      while(pos.first){
        fin[++cnt]=pos.first/2;
        pos=pre[pos.first][pos.second];
      }
      while(cnt)printf("%d ",fin[cnt--]);
    }
    

      

    K. Process with Constant Sum

    留坑。

  • 相关阅读:
    项目后台的最新认识和对MVC封装性、可维护性的更深刻认识!
    java综述
    android模拟器里输出程序:HelloWorld
    JAVA程序员必去的网站
    1.MVC框架复习 2.Ajax加强 3.搜索建议 4,三级联动 5、刷新分页 6、Ajax局部动态更新数据
    jQuery的几个例子流程讲解
    1.jQuery基础语法 2.jQuery选择器、操作页面文档元素 3.jqueryDOM操作 4.jqueryCSS操作 5.Jquery事件 6.Jquery动画
    成功站长应具备的良好心态
    java的学习步骤方法书籍大总结
    Java常用类
  • 原文地址:https://www.cnblogs.com/clrs97/p/6809850.html
Copyright © 2020-2023  润新知