2012 金华网络赛小记

1001:没看

1002:没看

1003:没看

1006:最水的概率DP,也是我们队最早A的题,1A

1004: 队友敲了半天才发现方法错了,改了后1A

1008:注意到修改和询问的次数比较少,所以可以先利用容斥原理求出给定区间内与p互质的数的和,然后再考虑那些已经被改变的位置

1010:知道怎么求LCA的话,基本上属于模拟题,不过有一些trick,根节点的兄弟有一个,最近公共祖先不能是询问的两个点中的某一个,这道题错的比较惨

去除hdu系统的原因CE了两次,这道题5A。这场比赛我几乎被这道题废了,出题人专门搞trick,有意思么- -

1005:比赛还有半个小时不到,看到这种题肯定就想到有没有模板,于是乎猥琐的google了一下,然后再猥琐的贴模板,然后就A了。。。。

总结:这场比赛几乎没什么思考的时间,题目的质量不是很高吧,模板题、原题出在网络赛真心不太好。

贴几个代码吧

1010

#pragma warning (disable : 4786)
#include<cstdio>
#include<cstring>
#include<vector>
#include<string>
#include<iostream>
#include<map>
#include<queue>
#include<stack>
#include<set>
#include<algorithm>
using namespace std;
const int maxn = 40000;
const int M = 40000;
const int POW = 16;
int fa[maxn];
char in[maxn][65];
char xx[maxn][65];
char root[65];
struct Edge{
       int to;
       string name;
       bool operator < (const Edge &cmp) const {
          return name < cmp.name;
       }
};
set<Edge> link[maxn];
map<string,int> mp;
string rec[maxn];
string init[maxn];
int tot;
void add(string a,string b) {
    Edge k;
    k.to=mp[b];    k.name=b;
    link[mp[a]].insert(k);
    rec[mp[a]] = a;
}
void print(int u) {
    printf("%s\n",init[u].c_str());
    for(set<Edge>::iterator it=link[u].begin();it!=link[u].end();it++){
        int v=it->to;
        print(v);
    }
}
int d[maxn];
int p[maxn][POW];
void dfs(int u,int fa){  
    d[u]=d[fa]+1;  
    p[u][0]=fa;  
    for(int i=1;i<POW;i++) p[u][i]=p[p[u][i-1]][i-1];  
    for(set<Edge>::iterator it=link[u].begin();it!=link[u].end();it++){  
        int v=it->to;  
        if(v==fa) continue;  
        dfs(v,u);  
    }  
}  
int LCA( int a, int b ){  
    if( d[a] > d[b] ) a ^= b, b ^= a, a ^= b;  
    if( d[a] < d[b] ){  
        int del = d[b] - d[a];  
        for( int i = 0; i < POW; i++ ) if(del&(1<<i)) b=p[b][i];  
    }  
    if( a != b ){  
        for( int i = POW-1; i >= 0; i-- )   
            if( p[a][i] != p[b][i] )       a = p[a][i] , b = p[b][i];  
        a = p[a][0], b = p[b][0];  
    }  
    return a;  
}  

int f[maxn];
int main()
{
    int n,i,j,k,Q;
    char op[10];
    char name[65],name1[65],name2[65];
    while(scanf("%d",&n),n)    
    {
        tot=0;
        mp.clear();
        scanf("%s",in[0]);      strcpy(xx[0],in[0]);    
        mp[xx[0]]=++tot; 
        init[1]=in[0];
        for(i=0;i<=n;i++) link[i].clear();
        f[0] = 0;
        for(i=1;i<n;i++) 
        {
            scanf("%s",in[i]);
            int len=strlen(in[i]);
            int cnt=0;
            for(j=0;j<len;j++) 
            {
                if(in[i][j]=='.') cnt++;
                else break;
            }
            strcpy(xx[i],in[i]+cnt);
            mp[xx[i]]=++tot;
            init[tot]=in[i];
            int pre=f[cnt-1];
            add(xx[pre],xx[i]);
            fa[tot] = mp[xx[pre]];
            f[cnt]=i;
        }
        dfs(1,0);
        scanf("%d",&Q);
        int id1,id2,id,pa;
        while(Q--) 
        {
            scanf("%s",op);
            if(op[0]=='L') 
            {
                print(1);
            } 
            else if(op[0]=='b') 
            {
                scanf("%s",name);
                id=mp[name];
                pa=fa[id];
                if(id==1) printf("1\n");
                else  printf("%d\n",link[pa].size());
            } 
            else 
            {
                scanf("%s%s",name1,name2);
                id1=mp[name1],id2=mp[name2];
                int lca=LCA(id1,id2);
                if(lca==id1 || lca==id2)      printf("%s\n",rec[fa[lca]].c_str());
                else printf("%s\n",rec[lca].c_str());
                
            }
        }
    }
    return 0;
}

1005

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;

const int maxn=100020;
int n,m;
double dp[maxn];
struct Node{
    int u,v;
    bool operator <(const Node & t)const {
        return v>t.v;
    }
}p[maxn];

int pre[maxn];

int main(){
    int i,j;
    int u,v;
    while(scanf("%d%d",&n,&m)!=EOF && n+m){
        memset(dp,0,sizeof(dp));
        memset(pre,-1,sizeof(pre));
        for(i=0;i<m;i++){
            scanf("%d%d",&p[i].u,&p[i].v);
        }
        sort(p,p+m);
        for(i=0;i<m;i++){
            if(pre[p[i].v]!=-1)
                pre[p[i].u]=pre[p[i].v];
            else
                pre[p[i].u]=p[i].v;
        }
        for(i=n-1;i>=0;i--){
            double sum=0;
            for(j=1;j<7;j++){
                if(pre[i+j]==-1){
                    sum+=dp[i+j];
                }else{
                    sum+=dp[pre[i+j]];
                }
            }
            sum=sum/6.0+1.0;
            dp[i]=sum;
        }
        printf("%.4lf\n",dp[0]);
    }
    return 0;
}

1007

#include<cstdio>
#include<map>
#include<vector>
using namespace std;
int gcd(int a,int b){return b?gcd(b,a%b):a;}
typedef __int64 lld;
vector<int>prime;
int nprime[1000]={1,1};
void init(){
    int i;
    int c;
    for(i=2;i<1000;++i){
        if(!nprime[i]){
            prime.push_back(i);
            for(c=i+i;c<1000;c+=i)nprime[c]=1;
        }
    }
}
lld getsum(int n,int r){
    vector<int>p;
    int i;
    for(i=0;prime[i]*prime[i]<=r;++i){
        if(r%prime[i]==0){
            p.push_back(prime[i]);
            while(r%prime[i]==0){
                r/=prime[i];
            }
        }
    }
    if(r>1)p.push_back(r);
     lld sum=(lld)n*(n+1)/2;
    for(int num=1;num<(1<<p.size());++num){
        lld mult=1;
        int ones=0;
        for(i=0;i<p.size();i++){
            if(num&(1<<i)){
                ones^=1;
                mult*=p[i];
            }
        }
        if(ones)sum-=(lld)(n/mult)*(n/mult+1)/2*mult;
        else sum+=(lld)(n/mult)*(n/mult+1)/2*mult;
    }
    return sum;
}

int main(){
    int t;
    scanf("%d",&t);
    init();
    while(t--){
        map<int,int>chg;
        map<int,int>::iterator it;
        int n,m;
        scanf("%d%d",&n,&m);
        int cmd;
        int x,y,c,p;
        while(m--){
            scanf("%d%d",&cmd,&x);
            if(cmd==1){
                scanf("%d%d",&y,&p);
                lld res=getsum(y,p)-getsum(x-1,p);
                for(it=chg.lower_bound(x);it!=chg.end()&&it->first<=y;++it){
                    if(gcd(it->first,p)==1)res-=it->first;
                    if(gcd(it->second,p)==1)res+=it->second;
                }
                printf("%I64d\n",res);
            }else{
                scanf("%d",&c);
                chg[x]=c;
            }
        }
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值