zoukankan      html  css  js  c++  java
  • 2017-10-湖南套题1

    复杂度m*logn是可以通过的,可以考虑每次询问时二分查找

    题目要求所有的线段没有交点,那么肯定是最靠近原点的两点连线,次靠近的。。。像这样:最下面是①号线,向上递增

    对于每次询问的(px,py),可以发现,在x=px这条直线上,对于每条线段的y是单调递增的,就可以二分是第几条线段的y>=px

    第i条可以,那么[1,i]条均可以,即可以有i个交点

     1 #include <algorithm>
     2 #include <cstdio>
     3 
     4 #define dou double
     5 
     6 const int N(1e5+5);
     7 struct ZhiXian {
     8     double k,b;
     9 }y[N];
    10 
    11 dou a[N],b[N],px,py;
    12 int n,m,ans[N];
    13 
    14 int L,R,Mid;
    15 inline bool check(int x)
    16 {
    17     return (px*y[x].k+y[x].b)<=py;
    18 }
    19 inline int erfen()
    20 {
    21     int ret=0;
    22     for(L=0,R=n; L<=R; )
    23     {
    24         Mid=L+R>>1;
    25         if(check(Mid))
    26         {
    27             ret=Mid;
    28             L=Mid+1;
    29         }
    30         else R=Mid-1;
    31     }
    32     return ret;
    33 }
    34 
    35 int Presist()
    36 {
    37     freopen("geometry.in","r",stdin);
    38     freopen("geometry.out","w",stdout);
    39     scanf("%d",&n);
    40     for(int i=1; i<=n; ++i) scanf("%lf",a+i);
    41     for(int i=1; i<=n; ++i) scanf("%lf",b+i);
    42     std::sort(a+1,a+n+1);std::sort(b+1,b+n+1);
    43     for(int i=1; i<=n; ++i)
    44         y[i].b=b[i],y[i].k=-b[i]/a[i];
    45     scanf("%d",&m);
    46     for(; m--; )
    47     {
    48         scanf("%lf%lf",&px,&py);
    49         printf("%d
    ",erfen());
    50     }
    51     return 0;
    52 }
    53 
    54 int Aptal=Presist();
    55 int main(int argc,char**argv){;}
    AC

     1 #include <cstdio>
     2 
     3 inline void read(int &x)
     4 {
     5     x=0; register char ch=getchar();
     6     for(; ch>'9'||ch<'0'; ) ch=getchar();
     7     for(; ch>='0'&&ch<='9'; ch=getchar()) x=x*10+ch-'0';
     8 }
     9 const int N(24);
    10 int n,a[N],b[N];
    11 
    12 int Presist()
    13 {
    14 //    freopen("cashier.in","r",stdin);
    15 //    freopen("cashier.out","w",stdout);
    16     int t; read(t);
    17     for(int i,j,k,x,y; t--; )
    18     {
    19         int ans=0;
    20         for(i=0; i<24; ++i) read(a[i]);
    21         for(i=0; i<24; ++i) read(b[i]);
    22         for(x,y,j,k,i=0; i<24; ++i)
    23         {
    24             for(j=i,x=0; a[i]>0&&++x<8; --j)
    25             {
    26                 if(j<0) j+=N;
    27                 if(!b[j]) continue;
    28                 if(b[j]>=a[i])
    29                 {
    30                     ans+=a[i];b[j]-=a[i];
    31                     for(k=(j+1)%N,y=0; ++y<8; ++k,k%=N)
    32                         if(k!=i) a[k]-=a[i]; a[i]=0;
    33                 }
    34                 else
    35                 {
    36                     ans+=b[j]; a[i]-=b[j];
    37                     for(k=(j+1)%N,y=0; ++y<8; ++k,k%=N)
    38                         if(k!=i) a[k]-=b[j];
    39                 }
    40             }
    41             if(a[i]>0) { ans=-1; goto print; }
    42         }
    43         /*for(x,y,j,k,i=0; i<8; ++i)
    44         {
    45             for(j=i,x=0; a[i]>0&&++x<8; --j,j+=N,j%=N)
    46             {
    47                 if(!b[j]) continue;
    48                 if(b[j]>=a[i])
    49                 {
    50                     ans+=a[i];b[j]-=a[i];
    51                     for(k=j+1,y=0; ++y<8; ++k,k+=N,k%=N)
    52                         if(k!=i) a[k]-=a[i]; a[i]=0;
    53                 }
    54                 else
    55                 {
    56                     ans+=b[j]; a[i]-=b[j];
    57                     for(k=j+1,y=0; ++y<8; ++k,k+=N,k%=N)
    58                         if(k!=i) a[k]-=b[j];
    59                 }
    60             }
    61             if(a[i]>0) { ans=-1; goto print; }
    62         }*/
    63         print:printf("%d
    ",ans);
    64     }
    65     return 0;
    66 }
    67 
    68 int Aptal=Presist();
    69 int main(int argc,char**argv){;}
    贪心45分,对与一个ai,从i向前找至多7个位置,直至可以把a[i]更新为0,每使用一次b[j],向后更新8个a[k],(每个人可以连续工作八小时)。。。然而这样会有许多问题

     差分约束

    设sum[i]表示使用的最小的b的前缀和,则ans=sum[23]

    sum[i]需要满足 (i>7) sum[i]-sum[i-8]>=a[i] ,0<=sum[i]-sum[i-1]<=b[i](i==0是特判向源点连)

            (i<8) sum[23]-sum[i+16]+sum[i]>=a[i]

    求最小值出现负环表示无解

     1 #include <cstring>
     2 #include <cstdio>
     3 #include <queue>
     4 
     5 #define max(a,b) (a>b?a:b)
     6 
     7 inline void read(int &x)
     8 {
     9     x=0; register char ch=getchar();
    10     for(; ch>'9'||ch<'0'; ) ch=getchar();
    11     for(; ch>='0'&&ch<='9'; ch=getchar()) x=x*10+ch-'0';
    12 }
    13 const int N(24);
    14 int n,a[N],b[N];
    15 
    16 int head[N+5],sumedge;
    17 struct Edge {
    18     int v,next,w;
    19     Edge(int v=0,int next=0,int w=0):v(v),next(next),w(w){;}
    20 }edge[N*N];
    21 
    22 inline void ins(int u,int v,int w)
    23 {
    24     edge[++sumedge]=Edge(v,head[u],w); head[u]=sumedge;
    25 }
    26 
    27 bool inq[N+5];
    28 int sum[N+5],cnt[N+5];
    29 bool SPFA()
    30 {
    31     std::queue<int>que;
    32     for(int i=0; i<N; ++i)
    33         inq[i]=cnt[i]=0,sum[i]=- 0x7fffffff;
    34     sum[N]=0;     que.push(N);
    35     for(int u,v; !que.empty(); )
    36     {
    37         u=que.front(); que.pop(); inq[u]=0;
    38         for(int i=head[u]; i; i=edge[i].next)
    39         {
    40             v=edge[i].v;
    41             if(sum[v]<sum[u]+edge[i].w)
    42             {
    43                 sum[v]=sum[u]+edge[i].w;
    44                 if(++cnt[v]>N) return 0;
    45                 if(!inq[v]) inq[v]=1,que.push(v);
    46             }
    47         }
    48     }
    49     return 1;
    50 }
    51 
    52 int L,R,Mid;
    53 inline bool check(int x)
    54 {
    55     memset(edge,0,sizeof(edge));
    56     memset(head,0,sizeof(head));
    57     sumedge=0;
    58     for(int i=0; i<24; ++i)
    59     {
    60         if(i>=8) ins(i-8,i,a[i]);
    61         else ins(i+16,i,a[i]-x);
    62         if(i) ins(i-1,i,0),ins(i,i-1,-b[i]);
    63         else ins(N,i,0),ins(i,N,-b[i]);
    64     }
    65     ins(N,23,x),ins(23,N,-x);
    66     return SPFA();
    67 }
    68 
    69 int Presist()
    70 {
    71     freopen("cashier.in","r",stdin);
    72     freopen("cashier.out","w",stdout);
    73     int t; read(t);
    74     for(int i,j,k,x,y; t--; )
    75     {
    76         int ans=-1;L=0,R=0;
    77         for(i=0; i<24; ++i) read(a[i]),L=max(L,a[i]);
    78         for(i=0; i<24; ++i) read(b[i]),R+=b[i];
    79         for(; L<=R; )
    80         {
    81             Mid=L+R>>1;
    82             if(check(Mid))
    83             {
    84                 R=Mid-1;
    85                 ans=Mid;
    86             }
    87             else L=Mid+1;
    88         }
    89         printf("%d
    ",ans);
    90     }
    91     return 0;
    92 }
    93 
    94 int Aptal=Presist();
    95 int main(int argc,char**argv){;}
    AC

     

     

     

     

     1 #include <cstdio>
     2 
     3 #define LL long long
     4 const int mod(1e9+7);
     5 const int N(50005);
     6 long long val[N];
     7 
     8 int Presist()
     9 {
    10     freopen("game.in","r",stdin);
    11     freopen("game.out","w",stdout);
    12     int n,m;    scanf("%d%d",&n,&m);
    13     for(int i=1; i<=n; ++i) scanf("%I64d",val+i);
    14     for(int oo,a,b,c; m--; )
    15     {
    16         scanf("%d%d%d",&oo,&a,&b);
    17         if(oo==1)
    18         {
    19             scanf("%d",&c);
    20             for(int i=a; i<=b; ++i)
    21             {
    22                 val[i]+=c;
    23                 for(; val[i]<0; ) val[i]+=mod;
    24                 for(; val[i]>=mod; ) val[i]-=mod;
    25             }
    26         }
    27         else if(oo==2)
    28             for(int i=a; i<=b; ++i)
    29             {
    30                 val[i]*=-1;
    31                 for(; val[i]<0; ) val[i]+=mod;
    32                 for(; val[i]>=mod; ) val[i]-=mod;
    33             }
    34         else
    35         {
    36             scanf("%d",&c);LL ans=0;
    37             for(int i=a; i<=b; ++i)
    38             {
    39                 ans+=val[i];
    40                 for(; ans<0; ) ans+=mod;
    41                 for(; ans>=mod; ) ans-=mod;
    42             }
    43             printf("%I64d
    ",ans);
    44         }
    45     }
    46     return 0;
    47 }
    48 
    49 int Aptal=Presist();
    50 int main(int argc,char**argv){;}
    20分,最暴力的暴力。(线段树炸了)

    k比较小,所以线段树每个节点维护一个区间答案记为f[i]

    考虑一段区间i,左边取j个右边就取i-j个 答案是每个方案的左边乘右边的和。

    就是i左儿子f[j]和右边的f[i-j] 所以f[i]=Σ(j=0~i) lc f[j]*rc f[i-j]

    考虑取反操作,i是奇数就取反,偶数无影响(因为是相乘)

    考虑区间加, 开始f[i] 是 a1*a2……an  后来是(a1+c)*(a2+c)……(an+c)

    考虑类似二项式定理,当上述a1~an  n个方案如果取了j个了,分别为al1,al2……alj

    那考虑最后答案,如果已经选了j个方案是(al1+c)(al2+c)……(alj+c)再还能选i-j个 最后答案是C(len-i,i-j)*f[j]*c^(i-j)

    复杂度 O(k^2*nlogn)

      1 #include <cstdio>
      2 #include <cstdlib>
      3 #define MOD 1000000007
      4 #define N 100005
      5 typedef long long LL;
      6 using namespace std;
      7 struct Node
      8 {
      9     LL f[11];
     10 } node[N * 4];
     11 LL a[N], lazy1[N * 4];
     12 bool lazy2[N * 4];
     13 LL C[N][11];
     14 
     15 Node merge(Node lc, Node rc)
     16 {
     17     Node o;
     18     o.f[0] = 1;
     19     for (int i = 1; i <= 10; i++)
     20     {
     21         o.f[i] = 0;
     22         for (int j = 0; j <= i; j++)
     23             o.f[i] = (o.f[i] + lc.f[j] * rc.f[i - j] % MOD) % MOD;
     24     }
     25     return o;
     26 }
     27 
     28 void build(int o, int l, int r)
     29 {
     30     if (l == r)
     31     {
     32         for (int i = 0; i <= 10; i++) node[o].f[i] = 0;
     33         node[o].f[0] = 1;
     34         node[o].f[1] = (a[l] % MOD + MOD) % MOD;
     35         return ;
     36     }
     37     int mid = (l + r) >> 1;
     38     build(o * 2, l, mid);
     39     build(o * 2 + 1, mid + 1, r);
     40     node[o] = merge(node[o * 2], node[o * 2 + 1]);
     41     return ;
     42 }
     43 
     44 void update1(int o, int l, int r, int c)
     45 {
     46     int len = r - l + 1;
     47     LL ff[11];
     48     for (int i = 0; i <= 10; i++) ff[i] = node[o].f[i];
     49     for (int i = 1; i <= 10; i++)
     50     {
     51         node[o].f[i] = 0;
     52         LL t = 1;
     53         for (int j = 0; j <= i; j++)
     54         {
     55             LL tmp = ff[i - j] * C[len - (i - j)][j] % MOD * t % MOD;
     56             node[o].f[i] = (node[o].f[i] + tmp) % MOD;
     57             t = t * c % MOD;
     58         }
     59     }
     60     return ;
     61 }
     62 
     63 void push_down(int o, int l, int r)
     64 {
     65     int mid = (l + r) >> 1;
     66     if (lazy1[o])
     67     {
     68         if (lazy2[o * 2])
     69             lazy1[o * 2] = (lazy1[o * 2] + MOD - lazy1[o]) % MOD;
     70         else
     71             lazy1[o * 2] = (lazy1[o * 2] + lazy1[o]) % MOD;
     72         if (lazy2[o * 2 + 1])
     73             lazy1[o * 2 + 1] = (lazy1[o * 2 + 1] + MOD - lazy1[o]) % MOD;
     74         else
     75             lazy1[o * 2 + 1] = (lazy1[o * 2 + 1] + lazy1[o]) % MOD;
     76         update1(o * 2, l, mid, lazy1[o]);
     77         update1(o * 2 + 1, mid + 1, r, lazy1[o]);
     78         lazy1[o] = 0;
     79     }
     80     if (lazy2[o])
     81     {
     82         lazy2[o * 2] ^= 1;
     83         lazy2[o * 2 + 1] ^= 1;
     84         for (int j = 1; j <= 10; j += 2)
     85         {
     86             node[o * 2].f[j] = MOD - node[o * 2].f[j];
     87             node[o * 2 + 1].f[j] = MOD - node[o * 2 + 1].f[j];
     88         }
     89         lazy2[o] = 0;
     90     }
     91 }
     92 
     93 void modify1(int o, int l, int r, int ll, int rr, int c)
     94 {
     95     if (ll <= l && rr >= r)
     96     {
     97         if (lazy2[o]) lazy1[o] = (lazy1[o] + MOD - c) % MOD;
     98         else lazy1[o] = (lazy1[o] + c) % MOD;
     99         update1(o, l, r, c);
    100         return ;
    101     }
    102     int mid = (l + r) >> 1;
    103     push_down(o, l, r);
    104     if (ll <= mid) modify1(o * 2, l, mid, ll, rr, c);
    105     if (rr > mid) modify1(o * 2 + 1, mid + 1, r, ll, rr, c);
    106     node[o] = merge(node[o * 2], node[o * 2 + 1]);
    107     return ;
    108 }
    109 
    110 void modify2(int o, int l, int r, int ll, int rr)
    111 {
    112     if (ll <= l && rr >= r)
    113     {
    114         for (int i = 1; i <= 10; i += 2) node[o].f[i] = MOD - node[o].f[i];
    115         lazy2[o] ^= 1;
    116         return ;
    117     }
    118     int mid = (l + r) >> 1;
    119     push_down(o, l, r);
    120     if (ll <= mid) modify2(o * 2, l, mid, ll, rr);
    121     if (rr > mid) modify2(o * 2 + 1, mid + 1, r, ll, rr);
    122     node[o] = merge(node[o * 2], node[o * 2 + 1]);
    123     return ;
    124 }
    125 
    126 Node query(int o, int l, int r, int ll, int rr)
    127 {
    128     if (ll <= l && rr >= r)
    129         return node[o];
    130     int mid = (l + r) >> 1;
    131     push_down(o, l, r);
    132     if (rr <= mid) return query(o * 2, l, mid, ll, rr);
    133     if (ll > mid) return query(o * 2 + 1, mid + 1, r, ll, rr);
    134     Node lc = query(o * 2, l, mid, ll, rr);
    135     Node rc = query(o * 2 + 1, mid + 1, r, ll, rr);
    136     return merge(lc, rc);
    137 }
    138 
    139 int main(int argc, char ** argv)
    140 {
    141     freopen("game.in", "r", stdin);
    142     freopen("game.out", "w", stdout);
    143     int n, m;
    144     scanf("%d %d", &n, &m);
    145     C[0][0] = 1;
    146     for (int i = 1; i <= n; i++)
    147     {
    148         C[i][0] = 1;
    149         for (int j = 1; j <= 10; j++)
    150             C[i][j] = (C[i - 1][j - 1] + C[i - 1][j]) % MOD;
    151     }
    152     for (int i = 1; i <= n; i++)
    153         scanf("%d", &a[i]);
    154     build(1, 1, n);
    155     for (int i = 1; i <= m; i++)
    156     {
    157 
    158         int l, r, opt;
    159         scanf("%d%d%d",&opt, &l, &r);
    160         if (opt == 1)
    161         {
    162             int c;
    163             scanf("%d", &c);
    164             c = (c % MOD + MOD) % MOD;
    165             modify1(1, 1, n, l, r, c);
    166         }
    167         else if (opt == 2)
    168         {
    169             modify2(1, 1, n, l, r);
    170         }
    171         else
    172         {
    173             int k;
    174             scanf("%d", &k);
    175             Node o = query(1, 1, n, l, r);
    176             printf("%d
    ", o.f[k] % MOD);
    177         }
    178     }
    179     return 0;
    180 }
    std
    ——每当你想要放弃的时候,就想想是为了什么才一路坚持到现在。
  • 相关阅读:
    正则表达式
    前端开发工程师
    前端开发工程师
    Java开发工程师(Web方向)
    Java开发工程师(Web方向)
    Java开发工程师(Web方向)
    Java开发工程师(Web方向)
    Java开发工程师(Web方向)
    前端开发工程师
    前端开发工程师
  • 原文地址:https://www.cnblogs.com/Shy-key/p/7677070.html
Copyright © 2011-2022 走看看