NOI2015 Day1

来源:互联网 发布:修改jenkins的端口 编辑:程序博客网 时间:2024/04/24 03:54

不知不觉省选完已经颓了半个月了!!!还两个月就要NOI了。。很慌。。
前几天做NOI2016翻车以后。。今天开始先做2015Day1
第一题:
这么裸这么和善的并查集么。。(我才不会告诉你先做的时候看错了题结果竟然还有80。。数据不要这么水吧。。)

第二题:
这么SB的树剖吗!?Install就查询该点到根路径上0的个数,然后全部赋为1,Uninstall就查询以该点为跟的子树1的个数,然后赋为0。。

第三题:
这个题看起来好像也可做啊。。然而我最终还是只打了表。。还只有20分。
看看题解。哇,状压dp。
发现取一个数相当于取到它所有的质因数。然后大于根号500的质因数每个数最多只有一个(废话),小于根号500的质因数只有8个,8个!然后就可以状压了。
然后就是处理大于根号500的质因数的问题。我们可以将所有数按最大质因数(大于根号500的)排序。然后相邻相等的不重复处理就好辣!
f[i][j]表示第一个人状态为i,第二个人为j的方案数。
g[0/1][i][j]表示当前数放到第1/2个人后,第一个人状态为i,第二个人为j的方案数。
然后f[i][j]=g[0][i][j]+g[1][i][j]f[i][j])为什么要减呢?
因为都不取的算了两次呀~

T1

#include <cstdio>#include <iostream>#include <algorithm>#define N  100005using namespace std;int read(){    int x=0,f=1;char ch=getchar();    while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}    while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}    return x*f;}int n,T,tot;int father[N<<1],hash[N<<1];class Operation{    public:        int x,y;bool z;}e[N];bool operator <(Operation a,Operation b){    return a.z>b.z;}int Find(int x){    int l=1,r=tot,rtn;    while(l<=r)    {        int mid=l+r>>1;        if(hash[mid]>=x) rtn=mid,r=mid-1;        else l=mid+1;    }    return rtn;}int Findf(int x){    return father[x]==x?x:father[x]=Findf(father[x]);}void Input_Init(){    n=read();tot=0;    for(int i=1;i<=n;i++)    {        hash[++tot]=e[i].x=read();        hash[++tot]=e[i].y=read();        e[i].z=read();    }    sort(hash+1,hash+1+tot);    tot=unique(hash+1,hash+1+tot)-hash-1;    for(int i=1;i<=tot;i++) father[i]=i;}bool Solve(){    sort(e+1,e+1+n);    for(int i=1;i<=n;i++)    {        e[i].x=Find(e[i].x);        e[i].y=Find(e[i].y);        int fx=Findf(e[i].x),fy=Findf(e[i].y);        if(!e[i].z)        {            if(fx==fy)                 return false;        }           else            father[fx]=fy;    }    return true;}int main(){    T=read();    while(T--)    {        Input_Init();        if(Solve()) printf("YES\n");        else printf("NO\n");    }    return 0;}

T2

#include <cstdio>#include <iostream>#include <algorithm>#define N 100005using namespace std;int read(){    int x=0,f=1;char ch=getchar();    while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}    while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}    return x*f;}int n,cnt,m,ind;int b[N],p[N],nextedge[N];int son[N],fa[N],top[N],pos[N],Fpos[N],sz[N],deep[N];class Seg_Tree{    public:    int l,r,sum,tag;}e[N<<2];void Add(int x,int y){    cnt++;    b[cnt]=y;    nextedge[cnt]=p[x];    p[x]=cnt;}void Dfs(int x){    sz[x]=1;    for(int i=p[x];i;i=nextedge[i])    {        int v=b[i];        deep[v]=deep[x]+1;        Dfs(v);sz[x]+=sz[v];        son[x]=sz[son[x]]<sz[v]?v:son[x];    }}void dfs(int x,int root){    pos[x]=++ind;top[x]=root;Fpos[pos[x]]=x;    if(!son[x]) return;    dfs(son[x],root);    for(int i=p[x];i;i=nextedge[i])    {        int v=b[i];        if(v==son[x]) continue;        dfs(v,v);    }}void Build(int p,int l,int r){    e[p].l=l,e[p].r=r,e[p].tag=-1;    if(l==r) return;    int mid=l+r>>1;    Build(p<<1,l,mid);Build(p<<1|1,mid+1,r);}int Len(Seg_Tree a){    return a.r-a.l+1;}void pushdown(int p){    e[p<<1].sum=e[p].tag*Len(e[p<<1]);    e[p<<1|1].sum=e[p].tag*Len(e[p<<1|1]);    e[p<<1].tag=e[p].tag;e[p<<1|1].tag=e[p].tag;    e[p].tag=-1;}void pushup(int p){    e[p].sum=e[p<<1].sum+e[p<<1|1].sum;}int Query(int p,int x,int y){    int l=e[p].l,r=e[p].r,mid=l+r>>1;    if(l==x&&y==r)        return e[p].sum;    if(e[p].tag!=-1) pushdown(p);    if(y<=mid) return Query(p<<1,x,y);    if(x>mid) return Query(p<<1|1,x,y);    return Query(p<<1,x,mid)+Query(p<<1|1,mid+1,y);}void Update(int p,int x,int y,int z){    int l=e[p].l,r=e[p].r,mid=l+r>>1;    if(l==x&&y==r)    {        e[p].sum=Len(e[p])*z;        e[p].tag=z;return;    }    if(y<=mid) Update(p<<1,x,y,z);    else if(x>mid) Update(p<<1|1,x,y,z);    else Update(p<<1,x,mid,z),Update(p<<1|1,mid+1,y,z);    pushup(p);}void Install(int x){    int fx=top[x],ans=deep[x]+1;    while(fx!=1)    {        ans-=Query(1,pos[fx],pos[x]);        Update(1,pos[fx],pos[x],1);        x=fa[fx],fx=top[x];    }    ans-=Query(1,1,pos[x]);    Update(1,1,pos[x],1);    printf("%d\n",ans);}void Uninstall(int x){    printf("%d\n",Query(1,pos[x],pos[x]+sz[x]-1));    Update(1,pos[x],pos[x]+sz[x]-1,0);}int main(){    //freopen("D:\\oi\\in.txt","r",stdin);    n=read();    for(int i=2;i<=n;i++) Add(fa[i]=read()+1,i);    Dfs(1);dfs(1,1);Build(1,1,n);    m=read();    for(int i=1;i<=m;i++)    {        char ch[10];static int x;        scanf("%s",ch);x=read()+1;        if(ch[0]=='i') Install(x);        else Uninstall(x);    }    return 0;}

T3

#include <cstdio>#include <iostream>#include <algorithm>#include <cstring>#define N 100005const int Lim=255;using namespace std;typedef long long ll;int read(){    int x=0,f=1;char ch=getchar();    while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}    while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}    return x*f;}int n,mod;ll ans; int p[]={2,3,5,7,11,13,17,19};ll f[260][260],g[2][260][260];class Digit{    public:        int S,Big;}e[501];bool operator <(Digit a,Digit b){    return a.Big<b.Big;}int main(){    n=read(),mod=read();    for(int i=2,x;i<=n;i++)    {        x=i;        for(int j=0;j<8;j++)        {            if(i%p[j]>0) continue;            e[i].S|=(1<<j);            while(x%p[j]==0) x/=p[j];        }        e[i].Big=x;    }    sort(e+2,e+1+n);f[0][0]=1;    for(int i=2;i<=n;i++)    {        if(i==2||e[i].Big!=e[i-1].Big||e[i].Big==1)        {            memcpy(g[0],f,sizeof(g[0]));            memcpy(g[1],f,sizeof(g[1]));        }        for(int j=Lim;~j;j--)        {            for(int k=Lim;~k;k--)            {                if((j&k)>0) continue;                if((e[i].S&k)==0)                     g[0][j|e[i].S][k]+=g[0][j][k],g[0][j|e[i].S][k]%=mod;                if((e[i].S&j)==0)                    g[1][j][k|e[i].S]+=g[1][j][k],g[1][j][k|e[i].S]%=mod;            }        }        if(i==n||e[i].Big==1||e[i].Big!=e[i+1].Big)        {            for(int j=Lim;~j;j--)                for(int k=Lim;~k;k--)                {                    if((j&k)>0) continue;                    f[j][k]=(g[0][j][k]+g[1][j][k]-f[j][k]);                }        }    }    for(int i=0;i<=Lim;i++)    for(int j=0;j<=Lim;j++)        if((i&j)==0)            ans=(ans+f[i][j])%mod;    ans=(ans+mod)%mod;    printf("%lld\n",ans);    return 0;}
0 0