zoukankan      html  css  js  c++  java
  • [校内训练20_05_26]AB

    1.给出N*M的循环平面上的k对点,每对点可以按四个方向的某个方向连成矩形,问交的最大值。

    显然可以将每一维分开考虑。对于一维问题,数轴上的某一个点能作为交的条件是惟一的,将这些条件哈希起来统计一下即可。

    O(klogk)

     1 #include<bits/stdc++.h>
     2 #define p 13131
     3 using namespace std;
     4 typedef long long int ll;
     5 typedef unsigned long long ull;
     6 const int maxn=5E5+5;
     7 int n;
     8 int X,Y;
     9 ull Hash[maxn];
    10 inline int read()
    11 {
    12     char ch=getchar();
    13     while(!isdigit(ch))ch=getchar();
    14     int s=ch-'0';ch=getchar();
    15     while(isdigit(ch)){s=s*10+ch-'0';ch=getchar();}
    16     return s;
    17 }
    18 struct line
    19 {
    20     int l,r;
    21 }a[maxn],b[maxn];
    22 struct pt
    23 {
    24     int x;
    25     int num,type;
    26     bool operator<(const pt&A)const
    27     {
    28         return x==A.x?type<A.type:x<A.x;
    29     }
    30 }P[maxn*4];
    31 inline void init()
    32 {
    33     Hash[0]=1;
    34     for(int i=1;i<=500000;++i)
    35         Hash[i]=Hash[i-1]*p;
    36 }
    37 inline ll solve(line*A,int len)
    38 {
    39     map<ull,int>bucket;
    40     ull now=0;
    41     int tot=0;
    42     for(int i=1;i<=n;++i)
    43     {
    44         P[++tot]=(pt){A[i].l,i,1};
    45         P[++tot]=(pt){A[i].l,0,0};
    46         P[++tot]=(pt){A[i].r,i,2};
    47         P[++tot]=(pt){A[i].r,0,0};
    48     }
    49     P[++tot]=(pt){0,0,0};
    50     P[++tot]=(pt){len,0,0};
    51     sort(P+1,P+tot+1);
    52     int last=0;
    53     for(int i=1;i<=tot;++i)
    54     {
    55         if(P[i].type==2)
    56             now-=Hash[P[i].num];
    57         else if(P[i].type==1)
    58             now+=Hash[P[i].num];
    59         else
    60         {
    61             bucket[now]+=P[i].x-last;
    62             last=P[i].x;
    63         }
    64         last=P[i].x;
    65     }
    66     int ans=0;
    67     for(map<ull,int>::iterator pt=bucket.begin();pt!=bucket.end();++pt)
    68         ans=max(ans,(*pt).second);
    69     return ans;
    70 }
    71 int main()
    72 {
    73     freopen("master.in","r",stdin);
    74     freopen("master.out","w",stdout);
    75     ios::sync_with_stdio(false);
    76     init();
    77     n=read(),X=read(),Y=read();
    78     for(int i=1;i<=n;++i)
    79         a[i].l=read(),b[i].l=read(),a[i].r=read(),b[i].r=read();
    80     cout<<solve(a,X)*solve(b,Y)<<endl;
    81     return 0;
    82 }
    View Code

    2.一个仙人掌,求$sigma_{i<j}{f(i,j)*i*j}$,其中f(i,j)表示i,j间的最小割,乘法定义为异或。

    首先将每一位分开来考虑。对于一棵树,f(i,j)显然为两点间的最小值,因此将边权从大到小插入,每次统计插入的边两端的答案即可。

    对于一个仙人掌,若要割掉一个环,那么环上最小的边一定会被选中。因此对于一个环,将边权最小的边删去,环上其余的边的边权加上其边权即可。

    O(nlogw)

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 typedef long long int ll;
      4 const int maxn=2E5+5;
      5 int n,m;
      6 int size,head[maxn];
      7 struct edge
      8 {
      9     int to,next,w;
     10 }E[maxn*2];
     11 int tot,top;
     12 inline int read()
     13 {
     14     char ch=getchar();
     15     while(!isdigit(ch))ch=getchar();
     16     int s=ch-'0';ch=getchar();
     17     while(isdigit(ch)){s=s*10+ch-'0';ch=getchar();}
     18     return s;
     19 }
     20 struct pt
     21 {
     22     int x,y,w,id;
     23     pt(int a=0,int b=0,int c=0,int d=0):x(a),y(b),w(c),id(d){}
     24     inline bool operator<(const pt&A)const
     25     {
     26         return w>A.w;
     27     }
     28 }wait[maxn*2],S[maxn*2];
     29 inline void add(int u,int v,int w)
     30 {
     31     E[++size].to=v;
     32     E[size].next=head[u];
     33     E[size].w=w;
     34     head[u]=size;
     35 }
     36 bool vis[maxn],in[maxn],used[maxn*2];
     37 void dfs(int u,int F)
     38 {
     39     in[u]=vis[u]=1;
     40     for(int i=head[u];i;i=E[i].next)
     41     {
     42         int v=E[i].to;
     43         if(v==F)
     44             continue;
     45         if(vis[v])
     46         {
     47             if(in[v])
     48             {
     49                 S[++top]=pt(u,v,E[i].w,i);
     50                 int minn=INT_MAX,pos=0;
     51                 for(int j=top;;--j)
     52                 {
     53                     if(S[j].w<minn)
     54                         minn=S[j].w,pos=j;
     55                     used[S[j].id]=1;
     56                     if(S[j].x==v)
     57                         break;
     58                 }
     59                 for(int j=top;;--j)
     60                 {
     61                     if(j!=pos)
     62                         wait[++tot]=pt(S[j].x,S[j].y,S[j].w+minn);
     63                     --top;
     64                     if(S[j].x==v)
     65                         break;
     66                 }
     67             }
     68             continue;
     69         }
     70         else
     71         {
     72             S[++top]=pt(u,v,E[i].w,i);
     73             dfs(v,u);
     74             if(!used[i])
     75                 wait[++tot]=pt(u,v,E[i].w),--top;
     76         }
     77     }
     78     in[u]=0;
     79 }
     80 int sum0[maxn][22],sum1[maxn][22];
     81 struct UFO
     82 {
     83     int fa[maxn];
     84     inline void clear()
     85     {
     86         for(int i=0;i<=n;++i)
     87             fa[i]=i;
     88     }
     89     inline int find(int x)
     90     {
     91         return fa[x]==x?x:fa[x]=find(fa[x]);
     92     }
     93     inline void merge(int x,int y)
     94     {
     95         fa[find(x)]=find(y);
     96     }
     97 }U;
     98 inline ll get()
     99 {
    100     U.clear();
    101     memset(sum0,0,sizeof(sum0));
    102     memset(sum1,0,sizeof(sum1));
    103     for(int d=0;d<21;++d)
    104         for(int i=1;i<=n;++i)
    105             if(i&(1<<d))
    106                 sum1[i][d]=1;
    107             else
    108                 sum0[i][d]=1;
    109     ll s=0;
    110     for(int i=1;i<=tot;++i)
    111     {
    112         int x=wait[i].x,y=wait[i].y;
    113         x=U.find(x),y=U.find(y);
    114         for(int d=0;d<21;++d)
    115         {
    116             if(wait[i].w&(1<<d))
    117                 s+=((ll)sum0[x][d]*sum0[y][d]+(ll)sum1[x][d]*sum1[y][d])<<d;
    118             else
    119                 s+=((ll)sum0[x][d]*sum1[y][d]+(ll)sum1[x][d]*sum0[y][d])<<d;
    120             sum0[x][d]+=sum0[y][d];
    121             sum1[x][d]+=sum1[y][d];
    122         }
    123         U.merge(y,x);
    124     }
    125     return s;
    126 }
    127 inline void solve()
    128 {
    129     memset(vis,0,sizeof(vis));
    130     memset(head,0,sizeof(head));
    131     memset(used,0,sizeof(used));
    132     size=0;
    133     n=read(),m=read();
    134     for(int i=1;i<=m;++i)
    135     {
    136         int x=read(),y=read(),z=read();
    137         add(x,y,z);
    138         add(y,x,z);
    139     }
    140     top=tot=0;
    141     dfs(1,0);
    142 //    cout<<tot<<endl;
    143 //    for(int i=1;i<=tot;++i)
    144 //        cout<<"--- "<<wait[i].x<<" "<<wait[i].y<<" "<<wait[i].w<<endl;
    145 //    assert(tot+1==n);
    146     sort(wait+1,wait+tot+1);
    147     ll ans=0;
    148     cout<<get()<<endl;
    149 }
    150 int main()
    151 {
    152     freopen("okfly.in","r",stdin);
    153     freopen("okfly.out","w",stdout);
    154     ios::sync_with_stdio(false);
    155     int T=read();
    156     while(T--)
    157         solve();
    158     return 0;
    159 }
    View Code
  • 相关阅读:
    Exchange 2013与 Office Web Apps 整合
    SharePoint2013 以其他用户登录和修改AD域用户密码 功能
    sharepoint 2010 自定义页面布局
    sharepoint 2010 记录管理 对象模型
    SharePoint2010 对象模型 关联列表
    在SharePoint Server 2010中更改“我的网站”
    xenapp 6.5 客户端插件第一次安装总是跳到官网
    如何解决在Windows Server 2008 R2 上安装证书服务重启后出现 CertificationAuthority 91错误事件
    在Win7 Hyper-v虚拟机中挂接真实机的声卡
    win8 中如何删除 共享文件夹 用户名和密码
  • 原文地址:https://www.cnblogs.com/GreenDuck/p/12963018.html
Copyright © 2011-2022 走看看