• zoj4028 LIS,差分约束


    题意:给你以i为结尾的最长上升子序列的值,和每个值的区间范围求可行的a【i】

    题解:差分约束,首先满足l[i]<=a[i]<=r[i],可以建一个虚拟节点n+1,那么有a[n+1]-a[i]<=-l[i],a[i]-a[n+1]<=r[i],同时对于之前出现过f【i】(假设为j)的情况,此时a[i]>=a[j](保证没法转移),a[j]-a[i]<=0,还有对于从上一个f[i]-1转移过来的点j,有a[i]>a[j],即a[j]-a[i]<=-1

    //#pragma comment(linker, "/stack:200000000")
    //#pragma GCC optimize("Ofast,no-stack-protector")
    //#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
    //#pragma GCC optimize("unroll-loops")
    #include<bits/stdc++.h>
    #define fi first
    #define se second
    #define mp make_pair
    #define pb push_back
    #define pi acos(-1.0)
    #define ll long long
    #define vi vector<int>
    #define mod 1000000007
    #define C 0.5772156649
    #define ls l,m,rt<<1
    #define rs m+1,r,rt<<1|1
    #define pil pair<int,ll>
    #define pli pair<ll,int>
    #define pii pair<int,int>
    #define cd complex<double>
    #define ull unsigned long long
    #define base 1000000000000000000
    #define fio ios::sync_with_stdio(false);cin.tie(0)
    
    using namespace std;
    
    const double g=10.0,eps=1e-12;
    const int N=100000+10,maxn=1000000+10,inf=0x3f3f3f3f,INF=0x3f3f3f3f3f3f3f3f;
    
    struct edge {
        int to,Next,c;
    }e[maxn];
    int l[N],r[N],f[N];
    int last[N];
    ll dis[N];
    bool vis[N];
    int head[N],cnt,n;
    void add(int u,int v,int c)
    {
    //    printf("%d %d %d
    ",u,v,c);
        e[cnt].to=v;
        e[cnt].c=c;
        e[cnt].Next=head[u];
        head[u]=cnt++;
    }
    void spfa()
    {
        memset(vis,0,sizeof vis);
        for(int i=1;i<=n+1;i++)dis[i]=1e18;
        queue<int>q;
        q.push(n+1);
        vis[n+1]=1;dis[n+1]=0;
        while(!q.empty())
        {
    //        printf("%d
    ",q.front());
            int u=q.front();
            q.pop();
            vis[u]=0;
            for(int i=head[u];~i;i=e[i].Next)
            {
                int To=e[i].to;
                if(dis[To]>dis[u]+e[i].c)
                {
                    dis[To]=dis[u]+e[i].c;
                    if(!vis[To])
                    {
                        vis[To]=1;
                        q.push(To);
                    }
                }
            }
        }
        bool ok=1;
        for(int i=1;i<=n;i++)
        {
            if(ok)printf("%d",dis[i]);
            else printf(" %d",dis[i]);
            ok=0;
        }
        puts("");
    }
    int main()
    {
        int T;scanf("%d",&T);
        while(T--)
        {
            memset(last,0,sizeof last);
            cnt=0;
            memset(head,-1,sizeof head);
            scanf("%d",&n);
            for(int i=1;i<=n;i++)scanf("%d",&f[i]);
            for(int i=1;i<=n;i++)scanf("%d%d",&l[i],&r[i]);
            for(int i=1;i<=n;i++)
            {
                add(i,n+1,-l[i]);
                add(n+1,i,r[i]);
                if(last[f[i]])add(last[f[i]],i,0);
                if(f[i]>0)add(i,last[f[i]-1],-1);
                last[f[i]]=i;
            }
            spfa();
        }
        return 0;
    }
    /***********************
    
    ***********************/
    View Code
  • 相关阅读:
    一个页面从输入url到页面加载显示完成,中间都经历了什么
    获取鼠标点击的是那个键位、阻止鼠标点击的默认事件
    获取鼠标的位置
    图片上传
    jQuery实现瀑布流(pc、移动通用)
    怎么用js或jq点击展开,出现隐藏的DIV,点击收起DIV又隐藏起来.
    js商城倒计时
    页面跳转前动画加载,页面跳转后记住滚动位置
    乐观锁与悲观锁
    过滤器、监听器、拦截器的区别
  • 原文地址:https://www.cnblogs.com/acjiumeng/p/8975627.html
Copyright © 2020-2023  润新知