1.15考试总结

下午突然来了一次考试,不过还挺简单的,要是没有#define int long long被卡常我就AK了

T1-最短路板子题,跑个dijkstra即可

代码

#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,x,y,w,m,s,t,g,p,dis[100003],h[100003],ll[100003],px,vis[100003];
vector<int>l[100003],l1[100003];
struct node
{
    int x,di;
    bool operator <(const node &nx)const
    {
        return nx.di<di;
    }
}pp;
priority_queue<node>q;
signed main()
{
    scanf("%lld%lld%lld%lld%lld%lld",&n,&m,&s,&t,&g,&p);
    for(int i=1;i<=n;i++)
        scanf("%lld%lld",&h[i],&ll[i]);
    for(int i=1;i<=m;i++)
    {
        scanf("%lld%lld%lld",&x,&y,&w);
        l[x].push_back(y),l[y].push_back(x),l1[x].push_back(w),l1[y].push_back(w);
    }
    for(int i=1;i<=n;i++)
        dis[i]=1e9;
    dis[s]=0,pp.x=s,pp.di=0,q.push(pp);
    while(!q.empty())
    {
        pp=q.top(),q.pop(),px=pp.x,vis[px]=1;
        for(int j=0;j<l[px].size();j++)
            if(vis[l[px][j]]==0&&pp.di+l1[px][j]<dis[l[px][j]]&&((pp.di+l1[px][j])*p+h[l[px][j]]<ll[l[px][j]]||l[px][j]==t))
            {
                node txt;
                txt.x=l[px][j],txt.di=pp.di+l1[px][j],dis[txt.x]=txt.di,q.push(txt);
            }                       
    }
    if(dis[t]<=g)
        cout<<dis[t];
    else
        cout<<"wtnap wa kotori no oyatsu desu!"<<endl;
    return 0;           
}

T2-分块板子题,分块加二分即可

代码

#include<bits/stdc++.h>
using namespace std;
int n,l,r,c,q,a[1000003],tag[1000003],pos[1000003],m,b[1000003],ll,rr,mid,p,su;
char typ;
void update(int l1)
{
    for(int i=(pos[l1]-1)*m+1;i<=min(n,pos[l1]*m);i++)
        a[i]+=tag[pos[i]],b[i]=a[i];
    sort(b+(pos[l1]-1)*m+1,b+min(n,pos[l1]*m)+1);
    tag[pos[l1]]=0;
}
void add(int l1,int r1,int num)
{
    for(int i=l1;i<=min(r1,pos[l1]*m);i++)
        a[i]+=num;
    update(l1);
    if(pos[l1]!=pos[r1])
    {
        for(int i=(pos[r1]-1)*m+1;i<=r1;i++)
            a[i]+=num;
        update(r1);
    }
    for(int i=pos[l1]+1;i<=pos[r1]-1;i++)
        tag[i]+=num;
}
int ask(int l1,int r1,int num)
{
    int ans=0;
    update(l1),update(r1);
    for(int i=l1;i<=min(r1,pos[l1]*m);i++)
        if(a[i]>=num)
            ans++;
    if(pos[l1]!=pos[r1])
        for(int i=(pos[r1]-1)*m+1;i<=r1;i++)
            if(a[i]>=num)
                ans++;
    for(int i=pos[l1]+1;i<=pos[r1]-1;i++)
    {
        ll=(i-1)*m+1,rr=min(n,i*m),p=rr;
        while(ll<=rr)
        {
            mid=(ll+rr)/2;
            if(b[mid]+tag[pos[mid]]>=num)
                rr=mid-1;
            else
                ll=mid+1;
        }
        ans+=p-rr;
    }
    return ans;
}
int main()
{
    scanf("%d%d",&n,&q);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
        b[i]=a[i];
    }
    m=sqrt(n);
    for(int i=1;i<=n;i++)
        pos[i]=(i-1)/m+1;
    su=pos[n];
    for(int i=1;i<=su;i++)
        sort(b+(i-1)*m+1,b+min(n,i*m)+1);
    for(int i=1;i<=q;i++)
    {
        scanf("%s",&typ);
        scanf("%d%d%d",&l,&r,&c);
        if(typ=='A')
            cout<<ask(l,r,c)<<endl;
        else
            add(l,r,c);   
    }
    return 0;
}

T3-LCA板子题,LCA+前缀和维护一下即可

题目要求的是求一段路径的节点深度的k次方和,显然不能很直接的维护,我们可以发现一点性质,

代码

#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,m,x,y,dep[300003],fat[300003],son[300003],siz[300003],topl[300003],rt,k,ans;
long long mi[300003][55],su[55][300003];
vector<int>l[300003];
const long long mod=998244353;
void dfs1(int x1,int fa)
{
    dep[x1]=dep[fa]+1,siz[x1]=1,fat[x1]=fa;
    int maxx=0;
    for(int j=0;j<l[x1].size();j++)
        if(l[x1][j]!=fa)
        {
            dfs1(l[x1][j],x1);
            siz[x1]+=siz[l[x1][j]];
            if(siz[l[x1][j]]>maxx)
                maxx=siz[l[x1][j]],son[x1]=l[x1][j];
        }
}
void dfs2(int x1,int tp)
{
    topl[x1]=tp;
    if(son[x1])
        dfs2(son[x1],tp);
    for(int j=0;j<l[x1].size();j++)
        if(l[x1][j]!=fat[x1]&&l[x1][j]!=son[x1])
            dfs2(l[x1][j],l[x1][j]);    
}
int ask_root(int x1,int xx)
{
    while(topl[x1]!=topl[xx])
    {
        if(dep[topl[x1]]<dep[topl[xx]])
            swap(x1,xx);
        x1=fat[topl[x1]];
    }
    if(dep[x1]<dep[xx])
        swap(x1,xx);
    return xx;
}
signed main()
{
    scanf("%lld",&n);
    for(int i=1;i<n;i++)
    {
        scanf("%lld%lld",&x,&y);
        l[x].push_back(y),l[y].push_back(x);
    }
    for(long long i=1;i<n;i++)
    {
        mi[i][0]=1;
        for(long long j=1;j<=50;j++)
            mi[i][j]=mi[i][j-1]*i%mod,su[j][i]=(su[j][i-1]+mi[i][j])%mod;
    }
    dep[0]=0;   
    dfs1(1,0);
    dfs2(1,1);
    scanf("%lld",&m);
    for(int i=1;i<=m;i++)
    {
        scanf("%lld%lld%lld",&x,&y,&k);
        rt=ask_root(x,y);
        ans=(su[k][dep[x]-1]-su[k][dep[rt]-1]+su[k][dep[y]-1]-su[k][max(0ll,dep[rt]-2)]+2*mod)%mod;
        cout<<ans<<endl;
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/dzice/p/12198333.html