UESTC 2016 Summer Training #5 Div.2(未完待续)

来源:互联网 发布:彩票号码组合软件 编辑:程序博客网 时间:2024/05/29 17:40

A

#include <cstdio>#include <cstring>#include <vector>#define MAXN 100005#define mem(a) memset(a, 0, sizeof(a))using namespace std;int TreeArray[MAXN], Left[MAXN], Right[MAXN], Fork[MAXN];typedef vector<int> Ve;vector<Ve>Edge(MAXN);int N,M;int key;void init()//初始化数组和{    mem(Left);  mem(Right);    mem(Fork);  mem(TreeArray);    for(int i=0;i<MAXN;i++)Edge[i].clear();}void DFS(int node)//为每一个node添加一个左值和右值,表示这个节点所{    Left[node] = key;    for(int i=0;i<Edge[node].size();i++)    {        key+=1;        DFS(Edge[node][i]);    }    Right[node] = key;}int LowBit(int x)//返回的是2^k{    return x & (x ^ (x-1));}void Edit(int k, int num)//修改节点k,如果是添加一个,代入1,删除一个代入-1{    while(k <= N)    {        TreeArray[k] += num;        k += LowBit(k);    }}int GetSum(int k)//得到1...k的和{    int sum = 0;    while(k>=1)    {        sum += TreeArray[k];        k -= LowBit(k);    }    return sum;}void ReadDataAndDo(){    int a,b;    char ch;    for(int i=1;i<N;i++)//输入a,b把边存放在容器里面    {        scanf("%d%d", &a, &b);        Edge[a].push_back(b);    }    key = 1;    DFS(1);//为每一个节点对应一个左边界和右边界,他自己就存放在左边界里面,而它的管辖范围就是左边界到右边界    for(int i=1;i<=N;i++)    {        Fork[i] = 1;//最初每个Fork上都有一个苹果        Edit(i,1);//同时更新树状数组的值    }    scanf("%d%*c", &M);    for(int i=0;i<M;i++)    {        scanf("%c %d%*c", &ch, &b);        if(ch == 'Q')//b的子树就是[Left[b], right[b]]        {            printf("%d\n", GetSum(Right[b]) - GetSum(Left[b]-1));        }        else        {            if(Fork[b]) Edit(Left[b],-1);//由于每个节点的编号就是它的左值,所以直接修改左节点            else Edit(Left[b],1);            Fork[b] = !Fork[b];//变为相反的状态        }    }}int main(){    while(~scanf("%d", &N))    {        init();        ReadDataAndDo();    }    return 0;}

B

#include <bits/stdc++.h>  using namespace std;  int n,q,x;  int main(){      int a=0,b=0;      scanf("%d%d",&n,&q);      while(q--){          int tmp;          scanf("%d",&tmp);          if(tmp==1){              scanf("%d",&x);              a = (n+a-x)%n;              b = (n+b-x)%n;              if(x%2) swap(a,b); //x为奇数时,1,2的位置奇偶性必然改变成相反的          }else{              a = (a+n-1)%n;              b = (b+n+1)%n;              swap(a,b);//交换奇偶位置          }      }      for(int i=1; i<=n; i++){          if(i%2) printf("%d ",(a+i-1+n)%n+1);//1的位置递推所有奇数位置的编号          else printf("%d ",(b+i-1+n)%n+1); //2的位置递推所有偶数位置的编号      }      return 0;  }  

C

#include <stdio.h>#include <algorithm>#include <iostream>#include <string.h>#include <math.h>#define INF 0x3f3f3f3f#define eps 1e-6typedef long long LL;const double pi = acos(-1.0);const long long Mod = INF;using namespace std;int main(){    LL M,N;    cin >> N >> M;    LL k = 2;    LL a = N / M;    printf("%I64d",a);    N = (N - a * M) * k;    while(N)    {        a = N / M;        printf(" %I64d",a);        k++;        N = (N - a * M) * k;    }    puts("");    return 0;}

D

#include <stdio.h>#include <algorithm>#include <iostream>#include <string.h>#include <math.h>#define INF 0x3f3f3f3f#define eps 1e-6typedef long long LL;const double pi = acos(-1.0);const long long MOD = 1e9 + 7;using namespace std;struct node{    int u,v,w;}edge[10005];int dis[10005];int top;int fun(int N){    int u,v,w;    for(int i = 1;i <= N;i++)        dis[i] = INF;    dis[1] = 0;    for(int k = 0;k < N - 1;k++)        for(int i = 0;i < top;i++)        {            u = edge[i].u;            v = edge[i].v;            w = edge[i].w;            if(dis[u] + w < dis[v] && dis[u] < INF)                dis[v] = dis[u] + w;        }    for(int i = 0;i < top;i++)    {        u = edge[i].u;        v = edge[i].v;        w = edge[i].w;        if(dis[u] + w < dis[v] && dis[u] < INF)            return 0;    }    return 1;}void add(int u,int v,int w){    edge[top].u = u;    edge[top].v = v;    edge[top++].w = w;}int main(){    int F,N,M,W,T,S,E;    cin >> F;    while(F--)    {        top = 0;        cin >> N >> M >> W;        for(int i = 0;i < M;i++)        {            cin >> S >> E >> T;            add(S,E,T);            add(E,S,T);        }        for(int i = 0;i < W;i++)        {            cin >> S >> E >> T;            add(S,E,-T);        }        if(!fun(N))            puts("YES");        else            puts("NO");    }    return 0;}

E
题目大意:

妈妈烧了M根骨头分给n个孩子们,第i个孩子有两个参数Mini和Maxi,分别表示这个孩子至少要得到Mini根骨头,至多得到Maxi根骨头。
输出一个整数,表示妈妈有多少种分配方案(骨头不能浪费,必须都分给孩子们)。

思路:

所以我们可以通过换元法,让下界的限制变成得到简单形式。
但是很遗憾的是,对于上界的限制,我们无法直接计算出答案。
逆向思维
于是根据容斥原理来做有:

import java.io.*;  import java.math.BigInteger;  import java.util.*;  public class Main {      public static void main(String args[]) throws Exception {          InputStream inputStream = System.in;          OutputStream outputStream = System.out;          InputReader in = new InputReader(inputStream);          PrintWriter out = new PrintWriter(outputStream);          Task solver = new Task();          solver.main(in, out);          out.close();      }  }  class InputReader {      BufferedReader reader;      StringTokenizer tokenizer;      public InputReader(InputStream stream) {          reader = new BufferedReader(new InputStreamReader(stream));          tokenizer = null;      }      public String next() {          if (!hasNext())              throw new RuntimeException();          return tokenizer.nextToken();      }      boolean hasNext() {          while (tokenizer == null || !tokenizer.hasMoreTokens())              try {                  tokenizer = new StringTokenizer(reader.readLine());              } catch (Exception e) {                  return false;              }          return true;      }      public long nextLong() {          return Long.parseLong(next());      }      public int nextInt() {          return Integer.parseInt(next());      }  }  class Task {      BigInteger zero = BigInteger.ZERO;      BigInteger one = BigInteger.ONE;      BigInteger ten = BigInteger.TEN;      final int maxn = 50005;      BigInteger[] f=new BigInteger[maxn];      int[] A=new int [15];      int[] B=new int [15];      int n,m;      BigInteger ans;      BigInteger C(int n,int m)      {          if(m>n)              return zero;          m=Math.min(m, n-m);          BigInteger res=one;          for(int i=n;i>=n-m+1;--i)          {              res=res.multiply(BigInteger.valueOf(i)).divide(BigInteger.valueOf(n-i+1));          }          return res;      }      void gao(int x,int cnt,int remain)      {          if(x<0)          {              if((cnt&1)>0)                  ans=ans.subtract(C(remain+n-1,n-1));              else                  ans=ans.add(C(remain+n-1,n-1));              return;          }          gao(x-1,cnt,remain);          if(remain>B[x])              gao(x-1,cnt+1,remain-B[x]-1);      }      void main(InputReader in, PrintWriter out) throws Exception {          int i,j;          ans=zero;          int T;          T=in.nextInt();          for(int cas=0;cas<T;++cas)          {              ans=zero;              n=in.nextInt();              m=in.nextInt();              for(i=0;i<n;++i)              {                  A[i]=in.nextInt();                  B[i]=in.nextInt();                  m-=A[i];                  B[i]-=A[i];              }              if(m<0)              {                  out.println(0);              }              else if(m==0)              {                  out.println(1);              }              else              {                     gao(n-1,0,m);                  out.println(ans);              }          }      }  }  

F
题意:给你一个数N,让你用前N个数,通过N-1次加减乘除运算得到24。让你输出合法的计算过程。
做法:
当N<4时,很显然,无法得到24点;
当N>=4时,可以得到24点,这时,我们分成两种情况进行构造。
1)当N为偶数时,由1,2,3,4显然可以构造出24,剩下的N-4(偶数)个数只需两两相减,并最后与24相乘即可。
2)当N为奇数时,由1,2,3,4,5显然可以构造出24,剩下的N-5(偶数)个数只需两两相减,并最后与24相乘即可。具体实现方法见代码。

#include <stdio.h>#include <algorithm>#include <iostream>#include <string.h>#include <math.h>#define INF 0x3f3f3f3f#define eps 1e-6typedef long long LL;const double pi = acos(-1.0);const long long MOD = 1e9 + 7;using namespace std;int a[12] = {0};int main(){    int N;    cin >> N;    int ok = 1;    if(N < 4)    {        puts("NO");        return 0;    }    else        puts("YES");    if(N % 2 == 0)    {        printf("2 * 3 = 6\n");        printf("4 * 6 = 24\n");        printf("24 * 1 = 24\n");        for(int i = 5;i < N;i += 2)        {            printf("%d - %d = 1\n",i + 1,i);            printf("24 * 1 = 24\n");        }    }    else    {        printf("4 * 5 = 20\n");        printf("20 + 3 = 23\n");        printf("23 + 2 = 25\n");        printf("25 - 1 = 24\n");        for(int i = 6;i < N;i += 2)        {            printf("%d - %d = 1\n",i + 1,i);            printf("24 * 1 = 24\n");        }    }    return 0;}

G

#include<bits/stdc++.h>using namespace std;#define ll long long#define mod 1000000007#define esp 0.00000000001const int N=2e5+10,M=1e6+10,inf=1e9;#define mem(s) memset(s,0,sizeof(s))int n,m,head[N],t,vis[N],deep[N],fa[N][20];int a[N];int flag[N];struct ss {  int to,next;}e[N*2];void add(int u,int v) {   e[t].next=head[u];e[t].to=v;head[u]=t++;}void init() {  t=1;mem(head);mem(vis);mem(fa);mem(deep);mem(flag);}void dfs(int x) {    vis[x]=1;    for (int i=1; i<=18 ;i++) {        if(deep[x]<(1<<i)) break;        fa[x][i] = fa[fa[x][i-1]][i-1];    }    for (int i=head[x];i;i=e[i].next) {        if(vis[e[i].to]) continue;        deep[e[i].to]=deep[x]+1;        fa[e[i].to][0]=x;        dfs(e[i].to);    }}int RMQ_LCA(int x,int y) {    if(deep[x]<deep[y]) swap(x,y);    int d=deep[x]-deep[y];    for (int i=0; i<=18 ;i++)        if((1<<i)&d) x=fa[x][i];    for (int i=18; i>=0 ;i--) {        if(fa[x][i]!=fa[y][i]) {            x=fa[x][i];y=fa[y][i];        }    }    if(x==y) return x;    else return fa[x][0];}int Dis_LCA(int x,int y) {    int LCA= RMQ_LCA(x,y);    return (deep[x]+deep[y]-2*deep[LCA]);}struct is{    int pos,step,pre;};int main(){    int x,y,z,i,t;    while(~scanf("%d",&x))    {        queue<is>q;        init();        for(i=2;i<=x;i++)        scanf("%d",&a[i]);        for(i=x;i>=2;i--)        {            add(a[i],i);            add(i,a[i]);        }        dfs(1);        int maxdeep=0;        int pre=0;        is st;        st.pos=1;        st.step=0;        st.pre=0;        q.push(st);        flag[1]=1;        ll ans=0;        while(!q.empty())        {            is vv=q.front();            q.pop();            if(vv.pos!=1)            {                ans+=Dis_LCA(vv.pos,pre);            }            pre=vv.pos;            maxdeep=vv.step;            int pos=vv.pos;            for(i=head[vv.pos];i;i=e[i].next)            {                if(flag[e[i].to])                continue;                is en;                en.pos=e[i].to;                en.step=vv.step+1;                en.pre=vv.pos;                flag[e[i].to]=1;                q.push(en);            }        }        printf("%lld\n",ans);    }    return 0;}

I

#include <cstdio>#include <cstring>#include <cstdlib>#include <cmath>#include <vector>#include <queue>#include <stack>#include <map>#include <algorithm>#include <set>using namespace std;typedef long long ll;typedef unsigned long long Ull;#define MM(a,b) memset(a,b,sizeof(a));const double eps = 1e-10;const int  inf =0x7f7f7f7f;const double pi=acos(-1);const int maxn=40000;struct node {   int x,y;   bool operator<(const node&a) const{       return this->x<a.x;   }};vector<node> A,B;char s[10000];int main(){    int n;    while(~scanf("%d",&n))    {        A.clear();B.clear();        for(int i=1;i<=n;i++)        {            scanf("%s",s);            int l=0,r=0;            for(int j=0;s[j]!='\0';j++)            {                 if(s[j]=='(') r++;                 else if(!r) l++;                 else r--;            }            if(l>r) B.push_back((node){r,l-r});            else  A.push_back((node){l,r-l});        }        sort(A.begin(),A.end());        sort(B.begin(),B.end());        int cntA=0,cntB=0;        bool flag=true;        for(int i=0;i<A.size();i++)        {            if(A[i].x>cntA) {flag=false;break;}            cntA+=A[i].y;        }        for(int i=0;i<B.size();i++)        {            if(B[i].x>cntB) {flag=false;break;}            cntB+=B[i].y;        }        if(cntA!=cntB) flag=false;        printf("%s\n",flag?"Yes":"No");    }    return 0;}

K

题意:让你读完文章,并依次得到每个人的比赛次数。一共11个人,并且已经个了3个,你可以用这三个数检验你自己的答案。
傻逼题,细心阅读就可以了

#include <stdio.h>#include <algorithm>#include <iostream>#include <string.h>#include <math.h>#define INF 0x3f3f3f3f#define eps 1e-6typedef long long LL;const double pi = acos(-1.0);const long long Mod = INF;using namespace std;int a[12] = {5,20,12,2,1,4,6,1,4,4,1,0};int main(){    int n;    cin >> n;    printf("%d\n",a[n]);    return 0;}
0 0
原创粉丝点击