题目:链接: https://pan.baidu.com/s/163ycV64ioy7uML7AvRDTGw 密码: p86i

T1:

倍增求LCA,minn数组记录最小值

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
inline long long read()
{
    long long f=1,ans=0;char c;
    while(c<\'0\'||c>\'9\'){if(c==\'-\')f=-1;c=getchar();}
    while(c>=\'0\'&&c<=\'9\'){ans=ans*10+c-\'0\';c=getchar();}
    return ans*f;
}
long long q,a[500001],fa[500001][23],minn[500001][23];
struct node{
    long long x;long long y;
    long long nex;
}ss[1000001];
long long head[500001];
long long cnt=1;
void add(long long a,long long b)
{
    ss[cnt].x=a,ss[cnt].y=b;
    ss[cnt].nex=head[a],head[a]=cnt++;
    return;
}
long long deep[500001];
void dfs(long long f,long long fath)
{
    deep[f]=deep[fath]+1;
    minn[f][0]=min(a[f],a[fath]);
    fa[f][0]=fath;
    for(long long i=1;(1<<i)<=deep[f];i++) fa[f][i]=fa[fa[f][i-1]][i-1],minn[f][i]=min(minn[f][i-1],minn[fa[f][i-1]][i-1]);
    for(long long i=head[f];i!=-1;i=ss[i].nex)
        if(ss[i].y!=fath) dfs(ss[i].y,f);
}
long long n,m,s;
long long lca(long long u,long long v)
{
    long long sry=min(a[u],a[v]);
//    cout<<sry<<endl;
    if(deep[u]<deep[v]) swap(u,v);
    for(long long i=22;i>=0;i--)
        if(deep[u]-(1<<i)>=deep[v]) sry=min(sry,minn[u][i]),u=fa[u][i];
//        cout<<sry<<" "<<u<<" "<<v<<endl; 
    if(u==v) return sry;
    for(long long i=22;i>=0;i--)
    {
        if(fa[u][i]==fa[v][i]) continue;
        else 
        {
            sry=min(sry,minn[u][i]),sry=min(sry,minn[v][i]);
            u=fa[u][i],v=fa[v][i];
        }
    }
//    cout<<fa[u][0]<<endl;
    return min(sry,a[fa[u][0]]);
}
int main()
{
    memset(head,-1,sizeof(head));
    n=read(),q=read();
    for(long long i=1;i<=n;i++) a[i]=read();
    for(long long i=1;i<n;i++)
    {
        long long u=read(),v=read();
        add(u,v),add(v,u);
    }
    dfs(1,0);
    for(long long i=1;i<=q;i++)
    {
        long long u=read(),v=read();
        printf("%d\n",lca(u,v));
//        return 0;
    }
}/*
5 5
8 100 502 9 3
2 4
4 1
1 3
1 5
3 5
1 5
2 3
2 1
3 4
*/

View Code

T2:

桶排序,因为告诉你a[i]最大为1048575,异或和为a[i]^a[i+1]^……a[j],拿sort会超时

#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<cstdio>
using namespace std;
inline int read()
{
    int f=1,ans=0;char c;
    while(c<\'0\'||c>\'9\'){if(c==\'-\')f=-1;c=getchar();}
    while(c>=\'0\'&&c<=\'9\'){ans=ans*10+c-\'0\';c=getchar();}
    return f*ans;
}
int a[1048576],x[50005001];
int n,s[10001];
int main()
{
    n=read();int q=read();
    for(int i=1;i<=n;i++) s[i]=read();
    for(int i=1;i<=n;i++)
    {
        int sum=0;
        for(int j=i;j<=n;j++) sum^=s[j],a[sum]++;
    }
    int cnt=0;
    for(int i=0;i<=1048575;i++) 
        while(a[i]!=0) x[++cnt]=i,a[i]--;
    for(int i=1;i<=q;i++) 
    {
        int xx=read();
        printf("%d\n",x[xx]);
    }
}

View Code

T3:

先将每一个点想成一个区间,r[i]表示i的祖先节点所在区间的最右号,l同理,f为祖先,j=r[find(j)]+1表示因为j号节点的区间右侧为r[find(j)],所以可得。

将边权从小到大排序,区间覆盖即可

#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<cstdio>
using namespace std;
inline int read()
{
    int f=1,ans=0;char c;
    while(c<\'0\'||c>\'9\'){if(c==\'-\')f=-1;c=getchar();}
    while(c>=\'0\'&&c<=\'9\'){ans=ans*10+c-\'0\';c=getchar();}
    return f*ans;
}
int n,m;
int f[100001],r[100001],l[100001];
int find(int x)
{
    if(f[x]==x) return x;
    return f[x]=find(f[x]);
}
struct node{
    int ll,rr,v;
}x[100001];
bool cmp(node xx,node yy)
{
    return xx.v<yy.v;
}
int ans,sum;
void merge(int x1,int x2)
{
    int t1=find(x1),t2=find(x2);
    f[t2]=t1;
    l[t1]=min(l[t1],l[t2]);
    r[t1]=max(r[t1],r[t2]);
}
int main()
{
    n=read(),m=read();
    for(int i=1;i<=n;i++) f[i]=l[i]=r[i]=i;
    for(int i=1;i<=m;i++)  x[i].ll=read(),x[i].rr=read(),x[i].v=read();
    sort(x+1,x+m+1,cmp);
    for(int i=1;i<=m;i++)
    {
        int j=r[find(x[i].ll)]+1;
        while(j<=x[i].rr)
        {
            ans++;
            sum+=x[i].v;
            merge(x[i].ll,j);
            j=r[find(j)]+1;
        }
        if(ans==n-1) 
        {
            printf("%d\n",sum);
            return 0;
        }
    }
    cout<<-1;
}
/*
5 4
1 2 1
3 4 2
3 5 3
1 4 1
*/

View Code

 

版权声明:本文为si-rui-yang原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/si-rui-yang/p/9452332.html