1. 程式人生 > >2018 11.2 PION模擬賽

2018 11.2 PION模擬賽

期望:100 + 50 + 30 = 180

實際:0 + 50 + 30 =80

期望:100   實際:0

數值有負數,邊界應該設為-0x7f       此處 gg

/*
期望的分:50+ 
*/
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define MAXN 100010
using
namespace std; int n,tot,ans; int f[MAXN]; int num[MAXN],w[MAXN],a[MAXN]; int lchild[MAXN],rchild[MAXN]; int read(){ int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return
x*f; } void pre(int now){ if(now==0) return ; num[++tot]=now; if(rchild[now]) pre(rchild[now]); if(lchild[now]) pre(lchild[now]); } int main(){ //freopen("lpp.in","r",stdin); freopen("point.in","r",stdin); freopen("point.out","w",stdout); n=read();
for(int i=1;i<=n;i++) w[i]=read(); for(int i=1;i<=n;i++){ lchild[i]=read(); rchild[i]=read(); } pre(1); for(int i=1;i<=n;i++) a[i]=w[num[i]]; memset(f,-0x7f,sizeof(f)); for(int i=1;i<=n;i++){ if(a[i]>f[ans]) f[++ans]=a[i]; else{ int x=lower_bound(f+1,f+1+ans,a[i])-f; f[x]=a[i]; } } printf("%d\n",ans); } /* 10 -77 -24 21 6 -4 -69 -1 -19 76 -1 5 2 7 8 0 0 6 9 10 4 0 3 0 0 0 0 0 0 0 0 */
100

/*
期望:50+;
*/
#include<queue>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int n;
long long ans;
int a[100010],b[100010];
int read(){
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
void work(int l,int r){
    if(l==r)    return; 
    int mid=(l+r)/2; 
    work(l,mid);
    work(mid+1,r);
    int i=l,j=mid+1;
    int nb=0;
    while(i<=mid||j<=r){
        if(i>mid)    b[++nb]=a[j++];
        else if(j>r)    b[++nb]=a[i++];
        else{
            if(a[i]<a[j])    b[++nb]=a[i++];
            else{
                b[++nb]=a[j++];
                ans+=mid-i+1;
            }
        }
    }
    for(i=l;i<=r;++i)    a[i]=b[i-l+1];
}
int main(){
    //freopen("lpp.in","r",stdin);
    freopen("a.in","r",stdin);
    freopen("a.out","w",stdout);
    n=read();
    if(n==1){
        int x=read();int y=read();
        if(x>y)    swap(x,y);
        printf("%d\n",(y-x)*2-1);
    }
    else if(n==2){
        int x1=read();int y1=read();
        int x2=read();int y2=read();
        if(x1>y1)    swap(x1,y1);
        if(x2>y2)    swap(x2,y2);
        if(x1==x2&&y1==y2){ printf("0\n");return 0; }
        if(x1<x2&&y1>y2||x2<x1&&y2>y1){ printf("%d\n",(y1-x1)*2-1+(y2-x2)*2-1);return 0;}
        if(x2>y1||x1>y2){ printf("%d\n",(y1-x1)*2-1+(y2-x2)*2-1);return 0;}
        if(y1==x2||y2==x1){ printf("%d\n",(y1-x1)*2-1+(y2-x2)*2-1-1);return 0;}
        if(x2>x1&&x2<y1){ printf("%d\n",(y1-x1)*2-1+(y2-x2)*2-1-1-(y1-x2));return 0;}
        if(x1>x2&&x1<y2){ printf("%d\n",(y1-x1)*2-1+(y2-x2)*2-1-1-(y2-x1));return 0;}
    }
    else{
        for(int i=1;i<=100000;i++)    a[i]=i;
        for(int i=1;i<=n;i++){
            int x=read();int y=read();
            swap(a[x],a[y]);
        }
        work(1,100000);
        printf("%d\n",ans);
    }
}
50分暴力
/*
分成三部分討論
    第一部分:討論修改位置的數對答案的貢獻
    第二部分:討論修改部分的區間對答案的貢獻。
    第三部分:討論餘下未修改的對答案的貢獻。
       可以發現,第一部分用樹狀陣列暴力求逆序對維護。第二部分字首和差分維護,第三部分的貢獻為0.
*/
#include<queue>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int n,m;
long long ans;
int x[100010],y[100010],pos[200010];
int date[200010],T[200010],sum[200010];
int read(){
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
int lowbit(int x){
    return x&(-x);
}
void add(int x){
    for(int i=x;i<=n*2;i+=lowbit(i))    T[i]++;
}
long long  query(int x){
    long long bns=0;
    for(int i=x;i;i-=lowbit(i))    bns+=T[i];
    return bns;
}
int main(){
    freopen("a.in","r",stdin);
    freopen("a.out","w",stdout);
    n=read();
    for(int i=1;i<=n;i++){
        x[i]=read();
        y[i]=read();
        date[i]=x[i];date[i+n]=y[i];
        pos[i]=i;pos[i+n]=i+n;
    }
    sort(date+1,date+1+2*n);
    int num=unique(date+1,date+1+2*n)-date-1;
    for(int i=1;i<=num;i++)    sum[i]=sum[i-1]+date[i]-date[i-1]-1;
    for(int i=1;i<=n;i++){
        x[i]=lower_bound(date+1,date+1+num,x[i])-date;
        y[i]=lower_bound(date+1,date+1+num,y[i])-date;
        swap(pos[x[i]],pos[y[i]]);
    }
    for(int i=num;i>=1;i--){
        ans+=query(pos[i]);
        ans+=abs(sum[pos[i]]-sum[i]);
        add(pos[i]);
    }
    printf("%I64d",ans);
}
100

/*
期望:30
*/
#include<queue>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int n,q,tot;
int dad[200010],num[200010];
int to[400010],net[400010],head[200010];
int col[200010],vis[200010],into[200010];
struct nond{
    int l,r,col,vi;
}v[200010];
int read(){
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
void add(int u,int v){
    to[++tot]=v;net[tot]=head[u];head[u]=tot;
}
void bfs(int s,int a,int b){
    queue<int>que;
    if(col[s]==a)    col[s]=b;
    que.push(s);vis[s]=1;
    while(!que.empty()){
        int now=que.front();
        que.pop();
        for(int i=head[now];i;i=net[i])
            if(!vis[to[i]]){
                if(col[to[i]]==a)    col[to[i]]=b;
                if(col[to[i]]==col[s]){
                    vis[to[i]]=1;
                    que.push(to[i]);
                }
            }
    }
}
int main(){
    //freopen("lpp.in","r",stdin);
    freopen("simulator.in","r",stdin);
    freopen("simulator.out","w",stdout);
    n=read();q=read();
    for(int i=1;i<=n;i++)    col[i]=read();
    for(int i=1;i<n;i++){
        int u=read();
        int v=read();
        add(u,v);add(v,u);
        into[u]++;into[v]++;
    }
    if(n<=1000){
        for(int i=1;i<=q;i++){
            int a=read();int b=read();
            memset(vis,0,sizeof(vis));
            int num=0;
            for(int j=1;j<=n;j++)
                if(!vis[j]){
                    bfs(j,a,b);
                    num++;
                }
            printf("%d\n",num);
        }
    }
}
30分暴力
/*
我們考慮優化合並操作,我們發現把x變成y和把y變成x得到的答案是相同的,
所以我們在合併的時候以及更改顏色的時候都是把顏色少的改成顏色多的,並
且維護每種顏色實際的vector是哪個,然後就相當於啟發式合併。
每個點的複雜度是他的度數乘以它被統計答案的次數,
最差情況下每個點也只會被統計logN次答案,那麼複雜度就是logN *  
等於2NlogN
*/
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int n,q,tot,ans;
int id[200010];
int col[200010],size[200010],dad[200010];
int to[400010],net[400010],head[200010];
vector<int>vec[200010];
int read(){
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
void add(int u,int v){
    to[++tot]=v;net[tot]=head[u];head[u]=tot;
}
void dfs(int now){
    for(int i=head[now];i;i=net[i])
        if(dad[now]!=to[i]){
            dad[to[i]]=now;
            dfs(to[i]);
            if(col[to[i]]!=col[now])    ans++;
        }
}
void change1(int now){
    for(int i=head[now];i;i=net[i])
        if(col[to[i]]!=col[now])    ans--;
}
void change2(int now){
    for(int i=head[now];i;i=net[i])
        if(col[to[i]]!=col[now])    ans++;
}
int main(){
    freopen("simulator.in","r",stdin);
    freopen("simulator.out","w",stdout);
    n=read();q=read();
    for(int i=1;i<=n;i++){
        id[i]=i;
        col[i]=read();
        size[col[i]]++;
        vec[col[i]].push_back(i);
    }
    for(int i=1;i<n;i++){
        int u=read();
        int v=read();
        add(u,v);add(v,u);
    }
    add(0,1);add(1,0);col[0]=200010;
    dfs(0);//cout<<ans;
    for(int i=1;i<=q;i++){
        int a=read();int b=read();
        int xn=id[a],yn=id[b];
        if(size[xn]<=size[yn]){
            for(int j=0;j<vec[xn].size();j++){
                change1(vec[xn][j]);
                vec[yn].push_back(vec[xn][j]);
            }
            for(int j=0;j<vec[xn].size();j++)    col[vec[xn][j]]=yn;
            for(int j=0;j<vec[xn].size();j++)    change2(vec[xn][j]);
            size[yn]+=size[xn];
            size[xn]=0;id[b]=yn;
            vec[xn].clear();
        }
        else{
            for(int j=0;j<vec[yn].size();j++){
                change1(vec[yn][j]);
                vec[xn].push_back(vec[yn][j]);
            }
            for(int j=0;j<vec[yn].size();j++)    col[vec[yn][j]]=xn;
            for(int j=0;j<vec[yn].size();j++)    change2(vec[yn][j]);
            size[xn]+=size[yn];
            size[yn]=0;
            id[b]=xn;id[a]=0;
            vec[yn].clear();
        }
        printf("%d\n",ans);
    }
}
/*
6 3
1 2 1 1 1 2
1 2
1 3
2 4
2 5
5 6

*/
100