zoukankan      html  css  js  c++  java
  • 2020寒假 Day-2

    2020 China Collegiate Programming Contest Changchun Onsite

    F. Strange Memory

    直接想法是 启发式合并:拿重儿子合并轻儿子,每发现 $a_i $ ^$ a_j = a_{lca(i,j)}$ 就把$i $^$ j$ 加入答案。

    但直接合并是$O(n^2)$,考虑开个数组 $cnt[val][i][j]$ 表示权值为val的数的第 $i$ 位 为 $j$ 的个数。

    直接启发式合并即可。

    #include<bits/stdc++.h>
    using namespace std;
    const int N=1e5+500;
    #define pb push_back
    typedef long long ll;
    int a[N];
    int n;
    ll ans=0;
    vector<int>G[N];
    int size[N],son[N];
    int cnt[N*12][22][2];
    int Son;
    void dfs_size(int u,int fa){
      size[u]=1;
      for(int i=0;i<G[u].size();i++){
        int v=G[u][i];
        if(v==fa)continue;
        dfs_size(v,u);
        size[u]+=size[v];
        if(size[v]>size[son[u]])son[u]=v;
      }
    }
    
    void Count(int u,int fa,int num){
      int val=a[u]^num;
      
      for(int i=0;i<=20;i++){
        ans+=(1ll<<i)*cnt[val][i][!((u>>i)&1)];
      }
    
      for(int i=0;i<G[u].size();i++){
        int v=G[u][i];
        if(v==fa||v==Son)continue;
        Count(v,u,num);
      }
    
    }
    
    void add(int u,int fa,int keep){
        for(int i=0;i<=20;i++){
          cnt[a[u]][i][(u>>i)&1]+=keep;
        }
        for(int i=0;i<G[u].size();i++){
          int v=G[u][i];
          if(v==fa||v==Son)continue;
          add(v,u,keep);
        }
    }
    
    void dfs_ans(int u,int fa,bool keep){
        for(int i=0;i<G[u].size();i++){
          int v=G[u][i];
          if(v==fa||v==son[u])continue;
          dfs_ans(v,u,false);
        }
        
        if(son[u]){
          dfs_ans(son[u],u,true);
          Son=son[u];
        }
        for(int i=0;i<G[u].size();i++){
          int v=G[u][i];
          if(v==fa||v==son[u])continue;
          Count(v,u,a[u]);
          add(v,u,1);
        }
        Son=0;
        
        for(int i=0;i<=20;i++){
          cnt[a[u]][i][(u>>i)&1]++;
        }
        if(keep==0){
    
          add(u,fa,-1);
        }
        
    }
    
    int main(){
    
      cin>>n;
      memset(son,0,sizeof son);
      for(int i=1;i<=n;i++)scanf("%d",&a[i]);
      for(int i=1,u,v;i<n;i++){
        scanf("%d %d",&u,&v);
        G[u].push_back(v);
        G[v].push_back(u);
      }
      dfs_size(1,-1);
      dfs_ans(1,-1,0);
    
      cout<<ans<<endl;
      // system("pause");
      return 0;
    }
    View Code

    I - Intersection

     HDU - 5120 

    求圆环面积交:

    两个大圆面积交 - 一个大一个小面积交   -  一个大一个小面积交   + 两个小的面积交

    c#include<bits/stdc++.h>
    using namespace std;
    #define pb push_back
    const int N=1e5+500;
    double  pi=acos(-1.0);
    typedef long long ll;
    typedef  double db;
    db eps=1e-6;
    int sgn(db x){
      if(fabs(x)<eps)return 0;
      else return x<0?-1:1;
    }
    struct Point{
      db x,y;
      
      Point(double X=0,double Y=0){x=X;y=Y;}
      Point operator +(Point B){return Point(x+B.x,y+B.y);}
      Point operator -(Point B){return Point(x-B.x,y-B.y);}
      Point operator *(double k){return Point(x*k,y*k);}
      Point operator /(double k){return Point(x/k,y/k);}   
      friend bool operator<(Point A,Point B){
        return sgn(A.x-B.x)<0||(sgn(A.x-B.x)==0&&sgn(A.y-B.y)<0);
      }
      friend bool operator==(Point A,Point B){
        return sgn(A.x-B.x)==0&&sgn(A.y-B.y)==0;
      
      }
    
    };
    
    typedef Point Vector;
    double Cross(Vector A,Vector B){return A.x*B.y-A.y*B.x;}
    db Distance(Point A,Point B){return hypot(A.x-B.x,A.y-B.y);}
    double intersect(double x1,double y1,double r1,double x2,double y2,double r2){
        double s,temp,p,l,ans;
        l=sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));
        if(l>=r1+r2)    ans=0;
        else if(l<=abs(r1-r2)){
            if(r1<=r2)      ans=pi*r1*r1;
            else            ans=pi*r2*r2;
        }
        else{
            p=(l+r1+r2)/2;
            s=2*sqrt(p*(p-l)*(p-r1)*(p-r2));
            if(r1>r2){
                temp=x1;x1=x2;x2=temp;
                temp=y1;y1=y2;y2=temp; 
                temp=r1;r1=r2;r2=temp;
            }
            ans=acos((r1*r1+l*l-r2*r2)/(2*r1*l))*r1*r1+acos((r2*r2+l*l-r1*r1)/(2*r2*l))*r2*r2-s;
        }
        return ans;
    }
    
    int main(){
        int t;cin>>t;
        int kase=0;
        while(t--){
          db r,R;
          scanf("%lf %lf",&r,&R);
          Point A,B;
          scanf("%lf %lf",&A.x,&A.y);
          scanf("%lf %lf",&B.x,&B.y);
          db ans=intersect(A.x,A.y,R,B.x,B.y,R)-intersect(A.x,A.y,R,B.x,B.y,r)-intersect(A.x,A.y,r,B.x,B.y,R)+
          intersect(A.x,A.y,r,B.x,B.y,r);
          printf("Case #%d: %.6lf
    ",++kase,ans);
        }
    
    
    
        // system("pause");
        return 0;
    }
    View Code
  • 相关阅读:
    正则表达式体会
    checkbox、全选反选,获取值
    弹出窗体值回调
    页面点击任意js事件,触发360、IE浏览器新页面
    XML增、删、改
    面试题
    行列转换
    DataTable 和Json 字符串互转
    前台js与后台方法互调
    文件与base64二进制转换
  • 原文地址:https://www.cnblogs.com/littlerita/p/14291339.html
Copyright © 2011-2022 走看看