• 10.16模拟赛(湖南集训)


    题解:二分答案。

    二分OP最后相交的直线。

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define maxn 500010
    using namespace std;
    
    int n,m,l,r,mid,xp,yp;
    int zx[maxn],zy[maxn];
    
    inline int read(){
        char ch=getchar();int x=0,f=1;
        for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
        for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';
        return x*f;
    }
    
    bool check(int k){
        double kk;
        kk=-1.*zy[k]/(1.*zx[k]);
        /*kk*1.0*xp<<" "<<1.0*zy[k]不知道为什么直接相加某个数据是22e..+...,非要开新变量a,b存*/
        long double a=kk*1.0*xp,b=1.0*zy[k];
    //    cout<<a<<" "<<b<<endl;
    //    cout<<a+b<<endl;
        return (1.*yp)>=(long double)(a+b);
    }
    
    int main(){
        freopen("geometry.in","r",stdin);
        freopen("geometry.out","w",stdout);
        n=read();
        for(int i=1;i<=n;i++)zx[i]=read();
        for(int i=1;i<=n;i++)zy[i]=read();
        sort(zx+1,zx+n+1);sort(zy+1,zy+n+1);
        m=read();
        while(m--){
            xp=read();yp=read();
            l=1;r=n;int ans=0;
            while(l<=r){
                mid=(l+r)>>1;
                if(check(mid)){
                    ans=mid;
                    l=mid+1;
                }else r=mid-1;
            }
            printf("%d
    ",ans);
        }
        fclose(stdin);fclose(stdout);
        return 0;
    }

     

    题解:差分约束

    (目前不是很理解差分约束最大最小值什么的..但是思路还是会的。

    毕竟以前也做过差分约束的裸题...)

    设s[i]前0-i时刻一共安排了多少个人..就是前缀和。

    有这么几个约束条件。

    s[i]-s[i-1]>=0(都前缀和了,肯定大于等于0啊

    s[i]-s[i-1]<=b[i](题目说了,你就有这b[i]个人愿意在i上。

    这两个条件是显然的啦,还有几个约束条件,就是题目中说的必须要安排大于等于a[i]个人在i-i+1 

    i是时刻。

    当i>=8时,s[i]-s[i-8]>=a[i]。如果要求红色位置的人,也就是8-9的人大于等于a[i](a[8]),那么

    1--8在职的人数必须大于等于a[i],也就是覆盖蓝色部分的人数和必须>=a[i]。蓝色的格子,发现

    在任意一个蓝色格子的左端点安排人,都会覆盖红色格子。

    所以s[i]-s[i-8]>=a[i].

    当i<8时,s[23]-s[16+i]+s[i]>=a[i];(下标从0开始)。

    蓝色格子同上。

     

    但是最后一个式子不满足差分约束的形式,但我们发现s[23]是常量,也就是我们所求的答案,

    是具有单调性的。可以二分,也可以从小到大枚举,第一个满足条件的就是答案喽。

    然后跑spfa,没有解的条件是有负环。

    代码:

    #include<iostream>
    #include<cstdio>
    #include<queue>
    #include<algorithm>
    #include<cstring>
    #define maxn 50
    using namespace std;
    queue<int>q;
    
    int sumedge,ans,t;
    int head[maxn],a[maxn],b[maxn];
    int dis[maxn],vis[maxn];
    
    struct Edge{
        int x,y,z,nxt;
        Edge(int x=0,int y=0,int z=0,int nxt=0):
            x(x),y(y),z(z),nxt(nxt){}
    }edge[maxn<<1];
    
    void add(int x,int y,int z){
        edge[++sumedge]=Edge(x,y,z,head[x]);
        head[x]=sumedge;
    }
    
    bool spfa(){
        memset(vis,0,sizeof(vis));
        memset(dis,-0x3f,sizeof(dis));
        while(!q.empty())q.pop();
        q.push(0);dis[0]=0;vis[0]=1;
        while(!q.empty()){
            int now=q.front();q.pop();vis[now]=false;
            if(dis[now]>1000)return false;
            for(int i=head[now];i;i=edge[i].nxt){
                int v=edge[i].y;
                if(dis[v]<dis[now]+edge[i].z){
                    dis[v]=dis[now]+edge[i].z;
                    if(!vis[v]){
                        vis[v]=true;
                        q.push(v);
                    }
                }
            }
        }
        return true;    
    }
    
    bool check(int ans){
        memset(head,0,sizeof(head));sumedge=0;
        for(int i=9;i<=24;i++)add(i-8,i,a[i]);
        for(int i=1;i<=8;i++)add(i+16,i,a[i]-ans);
        for(int i=1;i<=24;i++){
            add(i-1,i,0);add(i,i-1,-b[i]);
        }
        add(0,24,ans);add(24,0,-ans);
        return spfa();
    }
    
    int main(){
        scanf("%d",&t);
        while(t--){
            for(int i=1;i<=24;i++)scanf("%d",&a[i]);
            for(int i=1;i<=24;i++)scanf("%d",&b[i]);
            ans=0;
            while(1){
                if(++ans>1000){
                    ans=-1;
                    break;
                }
                if(check(ans))break;
            }
            cout<<ans<<endl;
        }
    }

    std:

    #include <cstdio>
    #include <cstdlib>
    #define MOD 1000000007
    #define N 100005
    typedef long long LL; 
    using namespace std;
    struct Node {
        LL f[11];
    }node[N * 4];
    LL a[N], lazy1[N * 4];
    bool lazy2[N * 4];
    LL C[N][11];
    
    Node merge(Node lc, Node rc) {
        Node o;
        o.f[0] = 1;
        for (int i = 1; i <= 10; i++) {
            o.f[i] = 0;
            for (int j = 0; j <= i; j++)
                o.f[i] = (o.f[i] + lc.f[j] * rc.f[i - j] % MOD) % MOD;
        }
        return o;
    }
    
    void build(int o, int l, int r) {
        if (l == r) {
            for (int i = 0; i <= 10; i++) node[o].f[i] = 0;
            node[o].f[0] = 1;
            node[o].f[1] = (a[l] % MOD + MOD) % MOD;
            return ;
        }
        int mid = (l + r) >> 1;
        build(o * 2, l, mid);
        build(o * 2 + 1, mid + 1, r);
        node[o] = merge(node[o * 2], node[o * 2 + 1]);
        return ;
    }
    
    void update1(int o, int l, int r, int c) {
        int len = r - l + 1;
        LL ff[11];
        for (int i = 0; i <= 10; i++) ff[i] = node[o].f[i];
        for (int i = 1; i <= 10; i++) {
            node[o].f[i] = 0;
            LL t = 1;
            for (int j = 0; j <= i; j++) {
                LL tmp = ff[i - j] * C[len - (i - j)][j] % MOD * t % MOD;
                node[o].f[i] = (node[o].f[i] + tmp) % MOD;
                t = t * c % MOD;
            }
        }
        return ;
    }
    
    void push_down(int o, int l, int r) {
        int mid = (l + r) >> 1;
        if (lazy1[o]) {
            if (lazy2[o * 2])
                lazy1[o * 2] = (lazy1[o * 2] + MOD - lazy1[o]) % MOD;
            else 
                lazy1[o * 2] = (lazy1[o * 2] + lazy1[o]) % MOD;
            if (lazy2[o * 2 + 1])
                lazy1[o * 2 + 1] = (lazy1[o * 2 + 1] + MOD - lazy1[o]) % MOD;
            else 
                lazy1[o * 2 + 1] = (lazy1[o * 2 + 1] + lazy1[o]) % MOD;
            update1(o * 2, l, mid, lazy1[o]);
            update1(o * 2 + 1, mid + 1, r, lazy1[o]);
            lazy1[o] = 0;
        }
        if (lazy2[o]) {
            lazy2[o * 2] ^= 1;
            lazy2[o * 2 + 1] ^= 1;
            for (int j = 1; j <= 10; j += 2) {
                node[o * 2].f[j] = MOD - node[o * 2].f[j];
                node[o * 2 + 1].f[j] = MOD - node[o * 2 + 1].f[j];
            }
            lazy2[o] = 0;
        }
    }
    
    void modify1(int o, int l, int r, int ll, int rr, int c) {
        if (ll <= l && rr >= r) {
            if (lazy2[o]) lazy1[o] = (lazy1[o] + MOD - c) % MOD;
            else lazy1[o] = (lazy1[o] + c) % MOD;
            update1(o, l, r, c);
            return ;
        }
        int mid = (l + r) >> 1;
        push_down(o, l, r);
        if (ll <= mid) modify1(o * 2, l, mid, ll, rr, c);
        if (rr > mid) modify1(o * 2 + 1, mid + 1, r, ll, rr, c);
        node[o] = merge(node[o * 2], node[o * 2 + 1]);
        return ;
    }
    
    void modify2(int o, int l, int r, int ll, int rr) {
        if (ll <= l && rr >= r) {
            for (int i = 1; i <= 10; i += 2) node[o].f[i] = MOD - node[o].f[i];
            lazy2[o] ^= 1;
            return ;
        }
        int mid = (l + r) >> 1;
        push_down(o, l, r);
        if (ll <= mid) modify2(o * 2, l, mid, ll, rr);
        if (rr > mid) modify2(o * 2 + 1, mid + 1, r, ll, rr);
        node[o] = merge(node[o * 2], node[o * 2 + 1]);
        return ;
    }
    
    Node query(int o, int l, int r, int ll, int rr) {
        if (ll <= l && rr >= r) 
            return node[o];
        int mid = (l + r) >> 1;
        push_down(o, l, r);
        if (rr <= mid) return query(o * 2, l, mid, ll, rr);
        if (ll > mid) return query(o * 2 + 1, mid + 1, r, ll, rr);
        Node lc = query(o * 2, l, mid, ll, rr);
        Node rc = query(o * 2 + 1, mid + 1, r, ll, rr);
        return merge(lc, rc);
    }
    
    int main(int argc, char ** argv) {
        freopen("game.in", "r", stdin);
        freopen("game.out", "w", stdout);
        int n, m;
        scanf("%d %d", &n, &m);
        C[0][0] = 1;
        for (int i = 1; i <= n; i++) {
            C[i][0] = 1;
            for (int j = 1; j <= 10; j++) 
                C[i][j] = (C[i - 1][j - 1] + C[i - 1][j]) % MOD;
        }
        for (int i = 1; i <= n; i++) 
            scanf("%d", &a[i]);
        build(1, 1, n); 
        for (int i = 1; i <= m; i++) {
    
            int l, r, opt;
            scanf("%d%d%d",&opt, &l, &r);
            if (opt == 1) {
                int c;
                scanf("%d", &c);
                c = (c % MOD + MOD) % MOD;
                modify1(1, 1, n, l, r, c);
            }
            else if (opt == 2) {
                modify2(1, 1, n, l, r);
            }
            else {
                int k;
                scanf("%d", &k);
                Node o = query(1, 1, n, l, r);
                printf("%d
    ", o.f[k] % MOD);
            }
        }
        return 0;
    }
  • 相关阅读:
    hadoop生态--ElasticSearch--ES操作
    Haoop生态--ElasticSeaarch(1)--ES预备知识(全文检索的概念、Lucence、倒排索引)
    hadoop生态--Hive(2)--Hive的使用方式
    hadoop生态--Zookeeper
    gsoap使用
    set容器
    如何杀死defunct进程
    关于多态
    数组类型与函数指针基本语法知识
    syslog日志
  • 原文地址:https://www.cnblogs.com/zzyh/p/7678986.html
Copyright © 2020-2023  润新知