zoukankan      html  css  js  c++  java
  • 2016大连网络赛

    1010 Weak Pair

    题解:树状数组/线段树 +离散化+dfs 对于每个a[i],将k/a[i]也放进去离散,这样的话对于每个数就能知道k/a[i]之前的有多少个数,从根节点开始dfs,然后找向它的子节点,看能不能匹配,而会造成影响的只有兄弟节点,那么在每次访问完一个节点的子节点之后删除这个点的贡献

    线段树版本:

      1 #include <iostream>
      2 #include <stdio.h>
      3 #include <string.h>
      4 #include <algorithm>
      5 #include <stdlib.h>
      6 #include <vector>
      7 #include <queue>
      8 #include <stack>
      9 #include <string>
     10 using namespace std;
     11 const int maxn=3*1e5+10;
     12 #define MS(a,b) memset(a,b,sizeof(a))
     13 long long a[maxn];
     14 long long b[maxn];
     15 long long k;
     16 int n,m;
     17 vector<int> G[maxn];
     18 int in[maxn];
     19 long long ans;
     20 struct node
     21 {
     22     int l,r;
     23     int mid(){return (l+r)>>1;}
     24     long long sum;
     25 };
     26 node tree[maxn<<2];
     27 void pushup(int rt)
     28 {
     29     tree[rt].sum=tree[rt<<1].sum+tree[rt<<1|1].sum;
     30 }
     31 void build(int l,int r,int rt)
     32 {
     33     tree[rt].l=l,tree[rt].r=r;
     34     tree[rt].sum=0;
     35     if(l==r) return ;
     36     int mid=tree[rt].mid();
     37     build(l,mid,rt<<1);
     38     build(mid+1,r,rt<<1|1);
     39 }
     40 void update(int index,int x,int L,int R,int rt)
     41 {
     42     if(L==index&&R==index)
     43     {
     44         tree[rt].sum+=x;
     45         return ;
     46     }
     47     int mid=tree[rt].mid();
     48     if(index<=mid) update(index,x,L,mid,rt<<1);
     49     else if(index>mid) update(index,x,mid+1,R,rt<<1|1);
     50     pushup(rt);
     51 }
     52 long long query(int l,int r,int L,int R,int rt)
     53 {
     54     if(L>=l&&R<=r) return tree[rt].sum;
     55     int mid=tree[rt].mid();
     56     long long ans=0;
     57     if(l<=mid) ans+=query(l,r,L,mid,rt<<1);
     58     if(r>mid) ans+=query(l,r,mid+1,R,rt<<1|1);
     59     return ans;
     60 }
     61 void dfs(int x)
     62 {
     63     int l=lower_bound(b+1,b+1+m,k/a[x])-b;
     64     int pos=lower_bound(b+1,b+1+m,a[x])-b;
     65     ans+=query(1,l,1,m,1);
     66     update(pos,1,1,m,1);
     67     for(int i=0;i<G[x].size();i++) dfs(G[x][i]);
     68     update(pos,-1,1,m,1);
     69 }
     70 void init()
     71 {
     72     for(int i=0;i<=n+1;i++) G[i].clear();
     73     build(1,m,1);
     74     MS(in,0);
     75     ans=0;
     76 }
     77 int main()
     78 {
     79     int T;
     80     scanf("%d",&T);
     81     while(T--)
     82     {
     83         //init();
     84         scanf("%d %lld",&n,&k);
     85         int cnt=1;
     86         for(int i=1;i<=n;i++)scanf("%lld",&a[i]);
     87             for(int i=1;i<=n;i++)
     88             {
     89                 b[cnt]=a[i];
     90                 cnt++;
     91                 b[cnt]=k/a[i];
     92                 cnt++;
     93             }
     94         m=cnt-1;
     95         sort(b+1,b+1+m);
     96         init();
     97         for(int i=1;i<=n-1;i++)
     98         {
     99             int x,y;
    100             scanf("%d %d",&x,&y);
    101             G[x].push_back(y);
    102             in[y]++;
    103         }
    104         int root;
    105         for(int i=1;i<=n;i++)
    106         {
    107             if(in[i]==0)
    108             {
    109                 root=i;
    110                 break;
    111             }
    112         }
    113         dfs(root);
    114         printf("%lld
    ",ans);
    115 
    116     }
    117     return 0;
    118 }
    View Code

      树状数组版本:

    #include <iostream>
    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    #include <stdlib.h>
    #include <vector>
    #include <queue>
    #include <stack>
    #include <string>
    using namespace std;
    const int maxn=3*1e5+10;
    #define MS(a,b) memset(a,b,sizeof(a))
    long long a[maxn];
    long long b[maxn];
    long long k;
    int n,m;
    vector<int> G[maxn];
    int in[maxn];
    long long ans;
    long long tree[maxn];
    void add(int pos,int x)
    {
        while(pos<=2*m)
        {
            tree[pos]+=x;
            pos+=(pos&(-pos));
        }
    }
    long long query(int pos)
    {
        long long sum=0;
        while(pos>0)
        {
            sum+=tree[pos];
            pos-=(pos&(-pos));
        }
        return sum;
    }
    void dfs(int x)
    {
        int l=lower_bound(b+1,b+1+m,k/a[x])-b;
        int pos=lower_bound(b+1,b+1+m,a[x])-b;
        ans+=query(l);
        add(pos,1);
        for(int i=0;i<G[x].size();i++) dfs(G[x][i]);
        add(pos,-1);
    }
    void init()
    {
        for(int i=0;i<=n+1;i++) G[i].clear();
        MS(tree,0);
        MS(in,0);
        ans=0;
    }
    int main()
    {
        int T;
        scanf("%d",&T);
        while(T--)
        {
            init();
            scanf("%d %lld",&n,&k);
            int cnt=1;
            for(int i=1;i<=n;i++)scanf("%lld",&a[i]);
                for(int i=1;i<=n;i++)
                {
                    b[cnt]=a[i];
                    cnt++;
                    b[cnt]=k/a[i];
                    cnt++;
                }
            m=cnt-1;
            sort(b+1,b+1+m);
            for(int i=1;i<=n-1;i++)
            {
                int x,y;
                scanf("%d %d",&x,&y);
                G[x].push_back(y);
                in[y]++;
            }
            int root;
            for(int i=1;i<=n;i++)
            {
                if(in[i]==0)
                {
                    root=i;
                    break;
                }
            }
            dfs(root);
            printf("%lld
    ",ans);
    
        }
        return 0;
    }
    View Code

    1009 Sparse Graph

    题解:就是求一个补图的最短路,考虑到实际上补图每条边的权值时一样的,那么可以使用bfs求一个最短路,用set保存访问过的点和没访问过的点,因为点如果访问过了,那么肯定肯定是最短的,再从已经访问到的点开始扩展,做完这题可以看看scu4444和这题的思路基本一样

     1 #include <iostream>
     2 #include <algorithm>
     3 #include <queue>
     4 #include <set>
     5 #include <stdio.h>
     6 #include <string.h>
     7 #include <stdlib.h>
     8 #include <map>
     9 #include <vector>
    10 #include <math.h>
    11 using namespace std;
    12 const int maxn=200*1000+10;
    13 int n,m;
    14 set<int> novis;
    15 set<int> vis;
    16 vector<int> G[maxn];
    17 int dis[maxn];
    18 void bfs(int s)
    19 {
    20     memset(dis,-1,sizeof(dis));
    21     queue<int> q;
    22     q.push(s);
    23     dis[s]=0;
    24     while(!q.empty()&&novis.size())
    25     {
    26         int x=q.front();
    27         q.pop();
    28         for(int i=0;i<G[x].size();i++)
    29         {
    30             if(!novis.count(G[x][i])) continue;
    31             novis.erase(G[x][i]);
    32             vis.insert(G[x][i]);
    33         }
    34         for(auto it:novis)
    35         {
    36             dis[it]=dis[x]+1;
    37             q.push(it);
    38         }
    39         novis.swap(vis);
    40         vis.clear();
    41         
    42     }
    43 }
    44 int main()
    45 {
    46     int T;
    47     scanf("%d",&T);
    48     while(T--)
    49     {
    50         vis.clear();
    51         novis.clear();
    52         scanf("%d %d",&n,&m);
    53         for(int i=1;i<=n;i++) G[i].clear();
    54         for(int i=1;i<=m;i++)
    55         {
    56             int x,y;
    57             scanf("%d %d",&x,&y);
    58             G[x].push_back(y);
    59             G[y].push_back(x);
    60         }
    61         int s;
    62         scanf("%d",&s);
    63         for(int i=1;i<=n;i++)
    64         {
    65             if(i==s) continue;
    66             novis.insert(i);
    67         }
    68         int cnt=1;
    69         bfs(s);
    70         for(int i=1;i<=n;i++)
    71         {
    72             if(i==s) continue;
    73             cnt++;
    74             printf("%d%c",dis[i],cnt==n?'
    ':' ');
    75             
    76         }
    77         
    78     }
    79     return 0;
    80 }
    View Code

    1008 Function

    题解:如果a>=b,那么a%b<=a/2;

    一个数n从本来的位置递减到0最多只需要logn次,也就是往右递减的位置最多不超过30个,那么我们就可以预处理出每个数往右递减的位置,然后离线询问,

    用一个优先队列存储数和数所在的位置,比如8 7 6 9 10,先push(8,1)进去,然后每次把队首拿出来,8%7=1,把(1,1)push进去,然后把(8,1)pop出来,(7,2)push进去,优先队列最大值优先,当队首元素小于当前元素的时候,把当前元素和位置push进去,开始枚举下一个数

     1 #include <iostream>
     2 #include <algorithm>
     3 #include <stdio.h>
     4 #include <string.h>
     5 #include <stdlib.h>
     6 #include <queue>
     7 using namespace std;
     8 const int maxn=1e5+10;
     9 struct node
    10 {
    11     int id;
    12     int data;
    13     int cnt;
    14     friend bool operator < (const node&a,const node&b)
    15     {
    16         return a.data<b.data;
    17     }
    18 };
    19 struct node2
    20 {
    21     int pos;
    22     int data;
    23     void init()
    24     {
    25         pos=0;
    26     }
    27 };
    28 node a[maxn];
    29 node2 pos[maxn][32];
    30 priority_queue<node> q;
    31 int main()
    32 {
    33     int T;
    34     scanf("%d",&T);
    35     while(T--)
    36     {
    37         while(!q.empty()) q.pop();
    38         int n;
    39         scanf("%d",&n);
    40         for(int i=1;i<=n;i++)
    41         {
    42             int x;
    43             scanf("%d",&x);
    44             a[i].data=x;
    45             a[i].id=i;
    46             a[i].cnt=0;
    47             pos[i][0].data=x;
    48             pos[i][0].pos=i;
    49             for(int j=1;j<=30;j++)
    50             {
    51                 pos[i][j].init();
    52             }
    53         }
    54         q.push(a[1]);
    55         for(int i=2;i<=n;i++)
    56         {
    57             node tmp;
    58             while(q.top().data>=a[i].data)
    59             {
    60                 tmp=q.top();
    61                 q.pop();
    62                 tmp.data%=a[i].data;
    63                 tmp.cnt+=1;
    64                 pos[tmp.id][tmp.cnt].pos=i;
    65                 pos[tmp.id][tmp.cnt].data=tmp.data;
    66                 q.push(tmp);
    67                 
    68             }
    69             q.push(a[i]);
    70         }
    71         int m;
    72         scanf("%d",&m);
    73         while(m--)
    74         {
    75             int l,r;
    76             int ans;
    77             scanf("%d %d",&l,&r);
    78             if(l==r){
    79                 printf("%d
    ",a[l].data);
    80                 continue;
    81             }
    82             else
    83             {
    84                 for(int i=0;i<=30;i++)
    85                 {
    86                     
    87                     if(pos[l][i].pos>r||pos[l][i].pos==0) break;
    88                     ans=pos[l][i].data;
    89                 }
    90                 printf("%d
    ",ans);
    91             }
    92         }
    93         
    94     }
    95     return 0;
    96 }
    View Code

    1006 Football Games

    题解:迷幻的题目。。。

     1 #include <iostream>
     2 #include <stdio.h>
     3 #include <string.h>
     4 #include <stdlib.h>
     5 #include <algorithm>
     6 #include <vector>
     7 #include <map>
     8 #include <queue>
     9 using namespace std;
    10 const int maxn=1e5;
    11 int b[maxn];
    12 int main()
    13 {
    14     int n,m;
    15     while(scanf("%d",&m)!=EOF)
    16     {
    17         while(m--)
    18         {
    19             scanf("%d",&n);
    20             int sum=0;
    21             for(int i=1;i<=n;i++)
    22             {
    23                 scanf("%d",&b[i]);
    24                 sum+=b[i];
    25             }
    26             bool flag=true;
    27             int cnt1=0,cnt2=0;
    28             for(int i=1;i<=n;i++)
    29             {
    30                 if(b[i]==0)
    31                 {
    32                     cnt1++;
    33                     if(cnt1>1)
    34                     {
    35                         flag=false;
    36                         break;
    37                     }
    38                 }
    39                 if(b[i]==2*(n-1))
    40                 {
    41                     cnt2++;
    42                     if(cnt2>1)
    43                     {
    44                         flag=false;
    45                         break;
    46                     }
    47                 }
    48                 if(b[i]>2*(n-1))
    49                 {
    50                     flag=false;
    51                     break;
    52                 }
    53             }
    54             if(sum!=n*(n-1)) flag=false;
    55             if(flag) printf("T
    ");
    56             else printf("F
    ");
    57         }
    58 
    59     }
    60     return 0;
    61 }
    View Code

     

  • 相关阅读:
    无限级分类表设计
    多表连接
    连接(上接子查询那一篇随笔)
    数据库中常用指令
    子查询
    mysql查询表达式解析
    mysql单表删除记录DELETE
    mysql 单表更新记录UPDATE
    七言
    时分秒计算案例
  • 原文地址:https://www.cnblogs.com/as3asddd/p/5861648.html
Copyright © 2011-2022 走看看