NOIP2013DAY1题解


T1转圈游戏

十月のsecret

题解:快速幂

代码:

#include<iostream>
#include<cstring>
#include<cstdio>
#define LL long long
using namespace std;

int n,m,k,x;

void read(int &x){
    char ch=getchar();x=0;int f=1;
    for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
    for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';
    x=x*f;
}

LL ksm(int x,int y){
    LL ret=1%n;
    while(y){
        if(y&1)ret=ret*x%n;
        x=x*x%n;
        y>>=1;
    }
    return ret;
}

int main(){
    freopen("circle.in","r",stdin);
    freopen("circle.out","w",stdout);
    read(n);read(m);read(k);read(x);
    cout<<(x%n+m*ksm(10,k)%n)%n<<endl;
    fclose(stdin);fclose(stdout);
    return 0;
}
AC

T2火柴排队

十月のsecret

题解:逆序对

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxn 100009
#define mod 99999997
using namespace std;

int ans,n,c[maxn],tree[maxn];

struct F{
    int h,id;
}a[maxn],b[maxn];

void read(int &x){
    char ch=getchar();x=0;int f=1;
    for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
    for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';
    x=x*f;
}

bool cmp(F a,F b){
    return a.h<b.h;
}

int lowbit(int x){
    return x&(-x);
}

void add(int x){
    while(x<=n){
        tree[x]++;
        x+=lowbit(x);
    }
}

int sum(int x){
    int ret=0;
    while(x){
        ret+=tree[x];
        x-=lowbit(x);
    }
    return ret;
}

int main(){
    freopen("match.in","r",stdin);
    freopen("match.out","w",stdout);
    read(n);
    for(int i=1;i<=n;i++)read(a[i].h),a[i].id=i;
    for(int i=1;i<=n;i++)read(b[i].h),b[i].id=i;
    sort(a+1,a+n+1,cmp);sort(b+1,b+n+1,cmp);
    for(int i=1;i<=n;i++)c[a[i].id]=b[i].id;
    for(int i=1;i<=n;i++){
        add(c[i]);
        ans=(ans%mod+(i-sum(c[i])%mod)%mod);
    }
    cout<<ans<<endl;
    fclose(stdin);fclose(stdout);
    return 0;
}
AC

T3货车运输

十月のsecret

题解:最大生成树+kruskal重构树

#include<iostream>
#include<cstdio>
#include<algorithm>
#define maxn 100009
#define maxm 500009
using namespace std;

int n,m,tot,sumedge,nn,qx;
int head[maxn],dad[maxn],deep[maxn],size[maxn],top[maxn],w[maxn],fa[maxn];

struct E{
    int x,y,z;
}e[maxm];

struct Edge{
    int x,y,nxt;
    Edge(int x=0,int y=0,int nxt=0):
        x(x),y(y),nxt(nxt){}
}edge[maxn<<1];

void add(int x,int y){
    edge[++sumedge]=Edge(x,y,head[x]);
    head[x]=sumedge;
}

bool cmp(E a,E b){
    return a.z>b.z;
}

int f(int x){
    fa[x]==x?x:fa[x]=f(fa[x]);
}

void dfs(int x){
    size[x]=1;deep[x]=deep[dad[x]]+1;
    for(int i=head[x];i;i=edge[i].nxt){
        int v=edge[i].y;
        if(v==dad[x])continue;
        dad[v]=x;
        dfs(v);
        size[x]+=size[v];
    }
}

void dfs_(int x){
    int s=0;
    if(!top[x])top[x]=x;
    for(int i=head[x];i;i=edge[i].nxt){
        int v=edge[i].y;
        if(v!=dad[x]&&size[v]>size[s])s=v;
    }
    if(s){
        top[s]=top[x];
        dfs_(s);
    }
    for(int i=head[x];i;i=edge[i].nxt){
        int v=edge[i].y;
        if(v!=dad[x]&&v!=s)dfs_(v);
    }
}

int lca(int x,int y){
    for(;top[x]!=top[y];){
        if(deep[top[x]]>deep[top[y]])swap(x,y);
        y=dad[top[y]];
    }
    if(deep[x]>deep[y])return w[y];
    return w[x];
}

int main(){
    freopen("truck.in","r",stdin);
    freopen("truck.out","w",stdout);
    scanf("%d%d",&n,&m);nn=n;
    for(int i=1;i<=m;i++)scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].z);
    sort(e+1,e+m+1,cmp);for(int i=1;i<=n;i++)fa[i]=i;
    for(int i=1;i<=m;i++){
        int fx=f(e[i].x),fy=f(e[i].y);
        if(fx!=fy){
            nn++;w[nn]=e[i].z;
            add(fx,nn);add(nn,fx);
            add(fy,nn);add(nn,fy);
            fa[nn]=nn;fa[fx]=nn;fa[fy]=nn;
            if(++tot==n-1)break;
        }
    }
    dfs(nn);dfs_(nn);
    scanf("%d",&qx);
    for(int i=1;i<=qx;i++){
        int x,y;
        scanf("%d%d",&x,&y);
        if(f(x)!=f(y))printf("-1\n");
        else printf("%d\n",lca(x,y));
    }
    fclose(stdin);fclose(stdout);
    return 0;
}
AC

树链剖分

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define inf 100000000
#define maxn 10009
using namespace std;

int n,m,q,sumedge,cnt,tot,qx;
int head[maxn],dad[maxn],deep[maxn],size[maxn],fe[maxn];
int w[maxn],top[maxn],re[maxn],tpos[maxn],fa[maxn];
struct E{
    int x,y,z;
}e[maxn*5];
struct Tree{
    int l,r,mn;
}tr[maxn<<2];

struct Edge{
    int x,y,z,nxt;
    Edge(int x=0,int y=0,int z=0,int nxt=0):
        x(x),y(y),z(z),nxt(nxt){}
}edge[maxn<<1];

void add(int x,int y,int z){
    edge[++sumedge]=Edge(x,y,z,head[x]);
    head[x]=sumedge;
}

bool cmp(E a,E b){
    return a.z<b.z;
}

int f(int x){
    return fa[x]==x?x:fa[x]=f(fa[x]);
}

void dfs(int x){
    size[x]=1;deep[x]=deep[dad[x]]+1;
    for(int i=head[x];i;i=edge[i].nxt){
        int v=edge[i].y;
        if(v==dad[x])continue;
        dad[v]=x;
        dfs(v);
        size[x]+=size[v];
    }
}

void dfs_(int x,int v){
    int s=0,t=0;tpos[x]=++cnt;re[cnt]=x;fe[x]=v;
    if(!top[x])top[x]=x;
    for(int i=head[x];i;i=edge[i].nxt){
        int v=edge[i].y;
        if(v!=dad[x]&&size[v]>size[s])s=v,t=edge[i].z;
    }
    if(s){
        top[s]=top[x];
        dfs_(s,t);
    }
    for(int i=head[x];i;i=edge[i].nxt){
        int v=edge[i].y;
        if(v!=dad[x]&&v!=s)dfs_(v,edge[i].z);
    }
}

int lca(int x,int y){
    for(;top[x]!=top[y];){
        if(deep[top[x]]>deep[top[y]])swap(x,y);
        y=dad[top[y]];
    }
    if(deep[x]>deep[y])return y;
    return x;
}

void pushup(int rt){
    tr[rt].mn=min(tr[rt<<1].mn,tr[rt<<1|1].mn);
}

void build(int rt,int l,int r){
    tr[rt].l=l;tr[rt].r=r;
    if(l==r){
        tr[rt].mn=fe[re[l]];
        return ;
    }
    int mid=(l+r)>>1;
    build(rt<<1,l,mid);build(rt<<1|1,mid+1,r);
    pushup(rt);
}

int query(int rt,int l,int r,int ql,int qr){
    if(l>=ql&&r<=qr){
        return tr[rt].mn;
    }
    int ans=inf,mid=(l+r)>>1;
    if(ql<=mid)ans=min(ans,query(rt<<1,l,mid,ql,qr));
    if(qr>mid)ans=min(ans,query(rt<<1|1,mid+1,r,ql,qr));
    return ans;
}

int query_mn(int x,int y){
    int ret=inf;
    for(;top[x]!=top[y];){
        if(deep[top[x]]>deep[top[y]])swap(x,y);
        ret=min(ret,query(1,1,n,tpos[top[y]],tpos[y]));
        y=dad[top[y]];
    }
    if(deep[x]>deep[y])swap(x,y);
    ret=min(ret,query(1,1,n,tpos[x]+1,tpos[y]));
    printf("%d\n",ret);
}

int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++)scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].z);
    for(int i=1;i<=n;i++)fa[i]=i;
    sort(e+1,e+m+1,cmp);
    for(int i=m;i>=1;i--){
        int x=e[i].x,y=e[i].y;
        int fx=f(x),fy=f(y);
        if(fx!=fy){
            fa[fx]=fy;tot++;
            add(x,y,e[i].z);
            add(y,x,e[i].z);
            if(tot==n-1) break;
        }
    }
    for(int i=1;i<=n;i++){
        if(size[i]==0){
            dfs(i);dfs_(i,0);
        }
    }
    build(1,1,n);
    scanf("%d",&qx);
    for(int i=1;i<=qx;i++){
        int x,y;
        scanf("%d%d",&x,&y);
        if(f(x)!=f(y))printf("-1\n");
        else
        query_mn(x,y);
    }
    return 0;
}
AC

优质内容筛选与推荐>>
1、新闻上一条下一条存储过程
2、asp调用webservice,终于搞定
3、<转>apache 默认目录的修改方法 .
4、ACM-ICPC 2018 焦作赛区网络预赛 G. Give Candies (打表找规律+快速幂)
5、WPF实例:通过WebServices获取城市的天气情况


长按二维码向我转账

受苹果公司新规定影响,微信 iOS 版的赞赏功能被关闭,可通过二维码转账支持公众号。

    阅读
    好看
    已推荐到看一看
    你的朋友可以在“发现”-“看一看”看到你认为好看的文章。
    已取消,“好看”想法已同步删除
    已推荐到看一看 和朋友分享想法
    最多200字,当前共 发送

    已发送

    朋友将在看一看看到

    确定
    分享你的想法...
    取消

    分享想法到看一看

    确定
    最多200字,当前共

    发送中

    网络异常,请稍后重试

    微信扫一扫
    关注该公众号





    联系我们

    欢迎来到TinyMind。

    关于TinyMind的内容或商务合作、网站建议,举报不良信息等均可联系我们。

    TinyMind客服邮箱:support@tinymind.net.cn