2019.10.29 csp-s模拟测试92 反思总结

今天快乐的墨雨笙因为什么而几乎爆零了呢?

顾此失彼+不会对拍+无脑的复杂度

今天高兴的墨雨笙又因为什么调了一个下午呢?

不明题意+不想范围+板子低级错误

 

R.I.P.

 

T1:

////害怕TLE,所以没有用while
//害怕不正确,所以两种情况又算了两次 
//细节全都考虑不清,何苦呢我……? 
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
const long long inf=1e15;
long long sum,ans,n,a,b,x,y,xx,yy,x2,y2,flag;
long long exgcd(long long a,long long b,long long &x,long long &y){
    if(!b){
        x=1,y=0;
        return a;
    }
    long long q=exgcd(b,a%b,x,y);
    long long z=x;
    x=y,y=z-(a/b)*y;
    return q;
}
int main()
{
//    freopen("1.in","r",stdin);
    scanf("%lld%lld%lld",&n,&a,&b);
    long long gcd=exgcd(a,b,x2,y2);
    if(b/gcd<a/gcd)swap(a,b),swap(x2,y2);//!
    for(int i=1;i<=n;i++){
        long long val;
        scanf("%lld",&val);
        if(flag)continue; 
        if(val<0)val=-val;//不,这个不用考虑也可以 
        ans=inf;
        if(val%a==0)ans=min(ans,val/a);
        if(val%b==0)ans=min(ans,val/b);
        x=x2,y=y2;
        if(val%gcd==0){
            x*=val/gcd,y*=val/gcd;
            long long b0=b/gcd,a0=a/gcd;
            xx=(x%b0+b0)%b0;//!
            yy=(val-xx*a)/b;
            while(abs(xx-b0)+abs(yy+a0)<abs(xx)+abs(yy))xx-=b0,yy+=a0;//!
            while(abs(xx+b0)+abs(yy-a0)<abs(xx)+abs(yy))xx+=b0,yy-=a0;
            ans=min(ans,(long long)abs(xx)+(long long)abs(yy));
            //实际上只有四个地方的点有可能产生贡献:
            //x为最小正整数解、x为最小负整数解、y为最小正整数解、y为最小负整数解
            //否则一定可以继续缩小 
        }
        if(ans==inf){
            flag=1;
        }
        else sum+=ans;
    }
    if(flag)printf("-1");
    else printf("%lld\n",sum);
    return 0;
 }
View Code

 

T2:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm> 
using namespace std;
const int N=3e5+10;
int n,c[2*N],cnt,T[N*20],L[N*20],R[N*20],tot,lst;
long long f[N],val,maxx[N],sum[N*20],ans;
struct node{
    int a,b,w;
}s[N];
bool cmp(node x,node y){
    return x.a==y.a?x.b<y.b:x.a<y.a;
}
void build(int &p,int l,int r){
    p=++tot;
    if(l==r)return;
    int mid=(l+r)/2;
    build(L[p],l,mid);
    build(R[p],mid+1,r);
}
long long query(int p0,int p,int l,int r,int l0,int r0){
    if(l0<=l&&r<=r0){
        return sum[p]-sum[p0];
    }
    int mid=(l+r)/2;
    if(r0<=mid)return query(L[p0],L[p],l,mid,l0,r0);
    else if(l0>mid)return query(R[p0],R[p],mid+1,r,l0,r0);
    else{
        return query(L[p0],L[p],l,mid,l0,mid)+query(R[p0],R[p],mid+1,r,mid+1,r0);
    }
}
void update(int p0,int &p,int l,int r,int pos,int val){
    p=++tot;
    sum[p]=sum[p0]+val,L[p]=L[p0],R[p]=R[p0];
    if(l==r)return;
    int mid=(l+r)/2;
    if(pos<=mid)update(L[p0],L[p],l,mid,pos,val);
    else update(R[p0],R[p],mid+1,r,pos,val);
}
int main()
{
//    freopen("pair.in","r",stdin);
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d%d%d",&s[i].a,&s[i].b,&s[i].w);
        c[++cnt]=s[i].a,c[++cnt]=s[i].b;
    }
    sort(c+1,c+cnt+1);
    cnt=unique(c+1,c+cnt+1)-c-1;
    sort(s+1,s+n+1,cmp);
    build(T[0],1,cnt);
    for(int i=1;i<=n;i++){
        int a1=lower_bound(c+1,c+cnt+1,s[i].a)-c;
        int b1=lower_bound(c+1,c+cnt+1,s[i].b)-c;
        while(lst<a1){
            maxx[lst+1]=maxx[lst];
            T[lst+1]=T[lst];
            lst++;
        }
        if(b1<a1)val=query(T[b1],T[a1],1,cnt,a1,cnt);
        else val=0;
        f[i]=maxx[min(b1,a1)]+val+s[i].w;
        maxx[a1]=max(maxx[a1],f[i]);
        update(T[a1],T[a1],1,cnt,b1,s[i].w);
        ans=max(ans,f[i]);
    }
    printf("%lld\n",ans);
    return 0;
}
个人玄学版本
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm> 
using namespace std;
const int N=3e5+10;
int n,cnt,T[N*18],L[N*18],R[N*18],tot;
long long f[N],c[2*N],val,maxx[N],sum[N*18],ans,aa[N];
struct node{
    long long a,b,w,a1,b1;
}s[N];
bool cmp(node x,node y){
    return x.a<y.a;
}
void build(int &p,int l,int r){
    p=++tot;
    sum[p]=0;
    if(l==r)return;
    int mid=(l+r)/2;
    build(L[p],l,mid);
    build(R[p],mid+1,r);
}
long long query(int p0,int p,int l,int r,int l0,int r0){
    if(l0<=l&&r<=r0){
        return sum[p]-sum[p0];
    }
    int mid=(l+r)/2;
    if(r0<=mid)return query(L[p0],L[p],l,mid,l0,r0);
    else if(l0>mid)return query(R[p0],R[p],mid+1,r,l0,r0);
    else{
        return query(L[p0],L[p],l,mid,l0,mid)+query(R[p0],R[p],mid+1,r,mid+1,r0);
    }
}
void update(int p0,int &p,int l,int r,long long pos,long long val){
    p=++tot;
    sum[p]=sum[p0]+val,L[p]=L[p0],R[p]=R[p0];
    if(l==r)return;
    int mid=(l+r)/2;
    if(pos<=mid)update(L[p0],L[p],l,mid,pos,val);
    else update(R[p0],R[p],mid+1,r,pos,val);
}
int main()
{
//    freopen("pair.in","r",stdin);
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%lld%lld%lld",&s[i].a,&s[i].b,&s[i].w);
        c[++cnt]=s[i].a,c[++cnt]=s[i].b;
    }
    sort(c+1,c+cnt+1);
    cnt=unique(c+1,c+cnt+1)-c-1;
    sort(s+1,s+n+1,cmp);
    build(T[0],1,cnt);
    for(int i=1;i<=n;i++){
        long long b1=lower_bound(c+1,c+cnt+1,s[i].b)-c;
        update(T[i-1],T[i],1,cnt,b1,s[i].w);
        aa[i]=s[i].a;
    }
    for(int i=1;i<=n;i++){
        long long a1=lower_bound(c+1,c+cnt+1,s[i].a)-c;
        long long b1=lower_bound(c+1,c+cnt+1,s[i].b)-c;
        int pos=upper_bound(aa+1,aa+n+1,s[i].b)-aa-1;
        if(pos>=i)pos=i-1;
        val=query(T[pos],T[i-1],1,cnt,a1,cnt);
        f[i]=maxx[pos]+val+s[i].w;
        maxx[i]=max(maxx[i-1],f[i]);
        ans=max(ans,f[i]);
    }
    printf("%lld\n",ans);
    return 0;
}
gls指点以后的清晰版本

 

T3:

#include<iostream>
#include<cstdio>
#include<queue>
using namespace std;
const int N=2e5+10;
const long long inf=1e18; 
int n,m,p;
int a[N],vis[N],tag[N];
int ver[2*N],Next[2*N],head[N],tot,xx[2*N];
long long dis[N],ans[N],edge[2*N];
priority_queue<pair<long long,int> >q;
void add(int x,int y,long long z){
    ver[++tot]=y;
    Next[tot]=head[x];
    head[x]=tot;
    edge[tot]=z;
    xx[tot]=x;
}
void dij(){
    for(int i=1;i<=n;i++){
        if(!dis[i])q.push(make_pair(0,i));
    }
    while(!q.empty()){
        while(vis[q.top().second]&&q.size())q.pop();
        if(q.empty())break;
        int x=q.top().second;
        q.pop();
        vis[x]=1;
        for(int i=head[x];i;i=Next[i]){
            int y=ver[i];
            long long z=edge[i];
            if(!vis[y]&&dis[x]+z<dis[y]){
                dis[y]=dis[x]+z;
                tag[y]=tag[x];
                q.push(make_pair(-dis[y],y));
            }
        }
    }
}
int main()
{
//    freopen("1.in","r",stdin);
    scanf("%d%d%d",&n,&m,&p);
    for(int i=1;i<=n;i++)dis[i]=inf;
    for(int i=1;i<=p;i++){
        scanf("%d",&a[i]);
        dis[a[i]]=0;
        tag[a[i]]=a[i];
    }
    for(int i=1;i<=n;i++)ans[i]=inf;
    for(int i=1,x,y;i<=m;i++){
        long long z;
        scanf("%d%d%lld",&x,&y,&z);
        add(x,y,z),add(y,x,z);
    }
    dij();
    for(int i=1;i<=tot;i+=2){
        int x=xx[i],y=ver[i];
        if(tag[x]!=tag[y]){
            long long d=dis[x]+dis[y]+edge[i];
            ans[tag[x]]=min(ans[tag[x]],d);
            ans[tag[y]]=min(ans[tag[y]],d);
        }
    }
    for(int i=1;i<=p;i++)printf("%lld ",ans[a[i]]);
    return 0;
}
View Code

 

 

别问,问就是死不足惜【大笑】

posted @ 2019-10-29 16:15  Chloris_Black  阅读(187)  评论(4编辑  收藏  举报