2019东北四省赛

B题

暴力题,通过维护数组表示在i位置能够取到数的大小

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e5+10;
int l[N];
vector<int> num[N];
int a[N],b[N];
ll f[N];
ll gcd(ll a,ll b){
    return b==0?a:gcd(b,a%b);
}
int main(){
    ios::sync_with_stdio(false);
    int t;
    cin>>t;
    while(t--){
        int n,m;
        cin>>n>>m;
        int i;
        memset(f,0,sizeof f);
        for(i=0;i<=m;i++)
            num[i].clear();
        for(i=1;i<=m;i++)
            cin>>l[i];
        for(i=1;i<=n;i++){
            cin>>a[i]>>b[i];
            num[b[i]].push_back(a[i]);
        }
        int mi=0x3f3f3f3f;
        int mx=0;
        for(i=1;i<=m;i++){
            sort(num[i].begin(),num[i].end());
            reverse(num[i].begin(),num[i].end());
            if((int)num[i].size()<l[i])
                continue;
            for(int j=0;j<(int)num[i].size();j++){
                f[max(j+1,l[i])]+=num[i][j];
            }
            mi=min(mi,(int)l[i]);
            mx=max(mx,(int)l[i]);
        }
        ll ans=0,d=1;
        double tmp=0;
        ll sum=0;
        for(i=mi;i<=mx;i++){
            sum+=f[i];
            if(1.0*sum/i>tmp){
                ans=sum;
                d=i;
                tmp=1.0*sum/i;
            }
        }
        ll dd=gcd(ans,d);
        ans/=dd;
        d/=dd;
        cout<<ans<<"/"<<d<<endl;
    }
    return 0;
}
View Code

C题

因为double有精度问题,所以不好去重,改成一般式就行

#include<bits/stdc++.h>
#define LL long long
using namespace std;
const int maxn=1e6+5;

struct Point
{
    LL x,y;
}pt1,pt2;

struct Line
{
    LL a,b,c;
    Line(Point s,Point e)
    {
        a=s.y-e.y;
        b=e.x-s.x;
        c=s.x*e.y-s.y*e.x;
    }
};

LL gcd(LL a,LL b)
{
    LL ans=(!b?a:gcd(b,a%b));
    if(ans==0)
        return 1;
    return ans;
}

pair<LL,LL>p1;
pair<pair<LL,LL>,LL>p2;
map<pair<LL,LL>,LL>mp1;
map<pair<pair<LL,LL>,LL>,LL>mp2;

int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        mp1.clear();
        mp2.clear();
        LL n;
        scanf("%lld",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%lld%lld%lld%lld",&pt1.x,&pt1.y,&pt2.x,&pt2.y);
            Line l=Line(pt1,pt2);
            LL g=gcd(l.a,l.b);
            LL a=l.a/g,b=l.b/g,c=l.c/g;
            p1=make_pair(a,b);
            p2=make_pair(p1,c);
            mp1[p1]++;
            mp2[p2]++;
        }
        LL ans=(LL)(n*(n-1)/2);
        for(auto it=mp1.begin();it!=mp1.end();it++)
            ans-=(it->second)*((it->second)-1)/2;

        for(auto it=mp2.begin();it!=mp2.end();it++)
            ans+=(it->second)*((it->second)-1)/2;
        printf("%lld\n",ans);
    }
    return 0;
}
View Code

D题

虚树

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6+10;
vector<int> num;
int dfn[N],id[N],tot,idx;
int h[N],ne[N],e[N],q[N];
int n,m,depth[N],times;
int f[N][30],u[N],v[N],k[N],opt[N];
int valf[N],pid[N];
ll val[N];
void add(int a,int b){
    e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
void init(){
    num.clear();
    memset(h,-1,sizeof h);
    idx=0;
    tot=0;
    for(int i=1;i<N;i++){
        k[i]=0;
        val[i]=0;
        pid[i]=0;
        valf[i]=0;
    }
}
void dfs(int u,int fa){
    dfn[u]=++times;
    f[u][0]=fa;
    depth[u]=depth[fa]+1;
    int i;
    for(i=h[u];i!=-1;i=ne[i]){
        int j=e[i];
        if(j==fa)
            continue;
        dfs(j,u);
    }
}
void pp(){
    int i,j;
    for(i=1;i<=27;i++){
        for(j=1;j<=n;j++){
            f[j][i]=f[f[j][i-1]][i-1];
        }
    }
}
bool cmp(int a,int b){
    return dfn[a]<dfn[b];
}
void addx(int a,int b){
    valf[b]=a;
    pid[b]=++tot;
}
int lca(int a,int b){
    if(depth[a]<depth[b])
        swap(a,b);
    int i;
    for(i=27;i>=0;i--){
        if(depth[f[a][i]]>=depth[b]){
            a=f[a][i];
        }
    }
    if(a==b)
        return a;
    for(i=27;i>=0;i--){
        if(f[a][i]!=f[b][i]){
            a=f[a][i];
            b=f[b][i];
        }
    }
    return f[a][0];
}
void build(){
    sort(num.begin(),num.end());
    num.erase(unique(num.begin(),num.end()),num.end());
    sort(num.begin(),num.end(),cmp);
    int tt=1;
    q[tt]=1;
    int i;
    for(i=0;i<(int)num.size();i++){
        if(num[i]==1)
            continue;
            int p=lca(num[i],q[tt]);
            if(p!=q[tt]){
                while(dfn[p]<dfn[q[tt-1]]){
                    addx(q[tt-1],q[tt]);
                    tt--;
                }
                if(dfn[p]!=dfn[q[tt-1]]){
                    addx(p,q[tt]);
                    q[tt]=p;
                }
                else{
                    addx(p,q[tt]);
                    tt--;
                }
            }
            q[++tt]=num[i];
    }
    for(i=1;i<tt;i++){
        addx(q[i],q[i+1]);
    }
}
ll get(int x,int d,int choice){
    if(choice==1){
        return x+d;
    }
    if(choice==2){
        return (x^d);
    }
    if(choice==3){
        return (x>=d?x-d:x);
    }
}
void modify(int x,int y,int d,int choice){
    int tmp[2]={x,y};
    int p=lca(x,y);
    for(int i=0;i<2;i++){
        int ans=tmp[i];
        while(ans!=p){
            val[ans]=get(val[ans],d,choice);
            val[n+pid[ans]]=get(val[n+pid[ans]],d,choice);
            //cout<<p<<" "<<valf[ans]<<endl;
            ans=valf[ans];
        }
    }
    val[p]=get(val[p],d,choice);
}
ll sum,xorsum,maxv,minv,minabs;
ll update(ll x,int d,int sz){
    sum+=1ll*sz*x;
    xorsum=xorsum^(sz%2*x);
    maxv=max(maxv,x);
    minv=min(minv,x);
    minabs=min(minabs,abs(x-d));
}
ll query(int x,int y,int d,int choice){
    int tmp[2]={x,y};
    int p=lca(x,y);
    sum=0,xorsum=0,maxv=0,minv=1<<30,minabs=1<<30;
    for(int i=0;i<2;i++){
        int ans=tmp[i];
        while(ans!=p){
            int sz=depth[ans]-depth[valf[ans]]-1;
            update(val[ans],d,1);
            if(sz){
                update(val[n+pid[ans]],d,sz);
            }
            ans=valf[ans];
        }
    }
    update(val[p],d,1);
    if(choice==4){
        return sum;
    }
    if(choice==5){
        return xorsum;
    }
    if(choice==6){
        return maxv-minv;
    }
    if(choice==7)
        return minabs;
}
int main(){
    //ios::sync_with_stdio(false);
    int t;
    cin>>t;
    while(t--){
        scanf("%d%d",&n,&m);
        init();
        int i,j;
        for(i=1;i<n;i++){
            int a,b;
            scanf("%d%d",&a,&b);
            add(a,b);
            add(b,a);
        }
        dfs(1,0);
        pp();
        for(i=1;i<=m;i++){
            scanf("%d%d%d",&opt[i],&u[i],&v[i]);
            num.push_back(u[i]);
            num.push_back(v[i]);
            if(opt[i]<=3||opt[i]==7){
                scanf("%d",&k[i]);
            }
        }
        build();
        for(i=1;i<=m;i++){
            if(opt[i]<=3){
                modify(u[i],v[i],k[i],opt[i]);
            }
            else{
                printf("%lld\n",query(u[i],v[i],k[i],opt[i]));
            }
        }
    }
}
View Code

 F题

博弈

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pll;
const int N=2e5+10;
int f[N][10];
int n,m;
int b[N],du[N][10];
string s,t;
vector<int> num[N];
int real1[N];
int pre(int x){
    if(x==1)
        return 6;
    else
        return x-1;
}
void solve(){
    queue<pll> q;
    int i,j;
    for(i=1;i<=n;i++){
        if(du[i][1]==0){
            for(j=1;j<=6;j++){
                if(s[j]=='A'){
                    f[i][j]=1;
                    q.push({i,j});
                }
                else{
                    f[i][j]=0;
                    q.push({i,j});
                }
            }
        }
    }
    while(q.size()){
        auto x=q.front();
        q.pop();
        for(auto e:num[x.first]){
            if(f[e][pre(x.second)]==-1){
                if(f[x.first][x.second]==b[pre(x.second)]){
                    f[e][pre(x.second)]=b[pre(x.second)];
                    q.push({e,pre(x.second)});
                }
                else{
                    du[e][pre(x.second)]--;
                    if(du[e][pre(x.second)]==0){
                        f[e][pre(x.second)]=b[pre(x.second)]^1;
                        q.push({e,pre(x.second)});
                    }
                }
            }
        }
    }
}
int main(){
    ios::sync_with_stdio(false);
    int T;
    cin>>T;
    while(T--){
        cin>>n>>m;
        memset(f,-1,sizeof f);
        memset(du,0,sizeof du);
        int i,j;
        for(i=0;i<=n;i++)
            num[i].clear();
        for(i=1;i<=m;i++){
            int a,b;
            cin>>a>>b;
            num[b].push_back(a);
            for(j=1;j<=6;j++){
                du[a][j]++;
            }
        }
        cin>>s>>t;
        s=" "+s;
        t=" "+t;
        for(i=1;i<=6;i++){
            real1[i]=s[i]-'A';
            b[i]=(t[i]-'0')^real1[i];
        }
        solve();
        for(i=1;i<=n;i++){
            if(f[i][1]==-1){
                cout<<'D';
            }
            else if(f[i][1]==1){
                cout<<'B';
            }
            else{
                cout<<'A';
            }
        }
        cout<<endl;
    }
}
View Code

H题

线段树维护差分数组,树状数组维护原数组的变更

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e5+10;
struct node{
    int l,r;
    ll sum;
}tr[N<<2];
ll tr2[N];
int a[N],b[N];
int n,m;
int lowbit(int x){
    return x&-x;
}
ll sum(int x){
    ll ans=0;
    int i;
    for(i=x;i;i-=lowbit(i)){
        ans+=tr2[i];
    }
    return ans;
}
void add(int x,int c){
    int i;
    for(i=x;i<=n;i+=lowbit(i)){
        tr2[i]+=c;
    }
}
void pushup(int u){
    tr[u].sum=max(tr[u<<1].sum,0ll)+max(tr[u<<1|1].sum,0ll);
}
void build(int u,int l,int r){
    if(l==r){
        tr[u]={l,r,a[l]};
    }
    else{
        tr[u]={l,r,0};
        int mid=l+r>>1;
        build(u<<1,l,mid);
        build(u<<1|1,mid+1,r);
        pushup(u);
    }
}
void modify(int u,int l,int x){
    if(tr[u].l==tr[u].r){
        tr[u].sum+=x;
        return ;
    }
    int mid=tr[u].l+tr[u].r>>1;
    if(l<=mid)
        modify(u<<1,l,x);
    else{
        modify(u<<1|1,l,x);
    }
    pushup(u);
}
ll query(int u,int l,int r){
    if(tr[u].l>=l&&tr[u].r<=r){
        return max(tr[u].sum,0ll);
    }
    int mid=tr[u].l+tr[u].r>>1;
    ll ans=0;
    if(l<=mid)
        ans+=query(u<<1,l,r);
    if(r>mid)
        ans+=query(u<<1|1,l,r);
    return ans;
}
int main(){
    //ios::sync_with_stdio(false);
    int t;
    cin>>t;
    while(t--){
        scanf("%d%d",&n,&m);
        int i;
        for(i=1;i<=n;i++)
            tr2[i]=0;
        for(i=1;i<=n;i++){
            scanf("%d",&a[i]);
            b[i]=a[i];
        }
        for(i=n;i>=1;i--){
            a[i]-=a[i-1];
        }
        for(i=1;i<=n;i++){
            add(i,a[i]);
        }
        build(1,1,n);
        for(i=1;i<=m;i++){
            int opt;
            scanf("%d",&opt);
            if(opt==1){
                int l,r,k;
                scanf("%d%d%d",&l,&r,&k);
                modify(1,l,k);
                add(l,k);
                if(r<n){
                    modify(1,r+1,-k);
                    add(r+1,-k);
                }
            }
            else{
                int l,r;
                scanf("%d%d",&l,&r);
                printf("%lld\n",sum(l)+query(1,1,r)-query(1,1,l));
            }
        }
    }
    return 0;
}
View Code

J题

签到

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=110;
int a[N];
int main(){
    ios::sync_with_stdio(false);
    int t;
    cin>>t;
    while(t--){
        int n;
        cin>>n;
        int i,j;
        for(i=1;i<=n;i++){
            cin>>a[i];
        }
        for(i=1;i<=50;i++){
            int flag=0;
            for(j=1;j<=n;j++){
                if(j==1){
                    if(i<3*a[j])
                    flag=1;
                }
                else{
                    if(i<a[j]+1){
                        flag=1;
                    }
                }
            }
            if(!flag&&i%2==0){
                cout<<i<<endl;
                break;
            }
        }

    }
    return 0;
}
View Code

 

posted @ 2020-11-04 21:31  朝暮不思  阅读(148)  评论(0编辑  收藏  举报