zoukankan      html  css  js  c++  java
  • 1821 最优集合(单调栈+模拟)

    1821 最优集合

    基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题

    一个集合S的优美值定义为:最大的x,满足对于任意i∈[1,x],都存在一个S的子集S',使得S'中元素之和为i。
    给定n个集合,对于每一次询问,指定一个集合S1和一个集合S2,以及一个数k,要求选择一个S2的子集S3(|S3|<=k),使得S1∪S3的优美值最大。
    (集合元素可以重复)

    Input

    第一行一个数n,(n<=1000) 接下来n行,每行描述一个集合: 第一个数m,表示集合大小,接下来m个数,表示集合中的元素(m<=1000,元素<=10^9) 第n+2行一个数T,表示询问次数(T<=10000) 接下来T行,每行3个数a,b,k,表示指定第a个集合为S1,第b个集合为S2,k的意义如题(a<=n,b<=n,k<=100,000)

    Output

    T行,每行一个数,表示对应询问所能达到的最大优美值

    Input示例

    2

    6 1 2 3 8 15 32

    6 1 1 1 1 1 1

    1

    1 2 3

    Output示例

    64

     

    //题解:先思考如何求出两个集合的优美值,如果 A 集合部分元素可以优美值为 x ,那么,如果 A 中有一个数是 y <= x+1 ,那么,优美值可以变为 x+y 。两个集合可以互补,如果将两个集合排好序,当仅靠 A 的元素优美值为 p 不能上升后,从 B 中选一个 <= p+1 的最大数补充,然后再考虑 A 集合的元素再扩大 p 。。。以此模拟即可,用单调栈优化 B 集合,每次查询约 2*m ,还有就是又是卡读入的题

     

      1 # include <cstdio>
      2 # include <cstring>
      3 # include <cstdlib>
      4 # include <iostream>
      5 # include <vector>
      6 # include <queue>
      7 # include <stack>
      8 # include <map>
      9 # include <bitset>
     10 # include <sstream>
     11 # include <set>
     12 # include <cmath>
     13 # include <algorithm>
     14 # pragma  comment(linker,"/STACK:102400000,102400000")
     15 using namespace std;
     16 # define LL          long long
     17 # define pr          pair
     18 # define mkp         make_pair
     19 # define lowbit(x)   ((x)&(-x))
     20 # define PI          acos(-1.0)
     21 # define INF         0x3f3f3f3f3f3f3f3f
     22 # define eps         1e-8
     23 # define MOD         1000000007
     24 
     25 namespace fastIO{
     26     #define BUF_SIZE 100000
     27     #define OUT_SIZE 100000
     28     #define ll long long
     29     //fread->read
     30     bool IOerror=0;
     31     inline char nc(){
     32         static char buf[BUF_SIZE],*p1=buf+BUF_SIZE,*pend=buf+BUF_SIZE;
     33         if (p1==pend){
     34             p1=buf; pend=buf+fread(buf,1,BUF_SIZE,stdin);
     35             if (pend==p1){IOerror=1;return -1;}
     36             //{printf("IO error!
    ");system("pause");for (;;);exit(0);}
     37         }
     38         return *p1++;
     39     }
     40     inline bool blank(char ch){return ch==' '||ch=='
    '||ch=='
    '||ch=='	';}
     41     inline void read(int &x){
     42         bool sign=0; char ch=nc(); x=0;
     43         for (;blank(ch);ch=nc());
     44         if (IOerror)return;
     45         if (ch=='-')sign=1,ch=nc();
     46         for (;ch>='0'&&ch<='9';ch=nc())x=x*10+ch-'0';
     47         if (sign)x=-x;
     48     }
     49     inline void read(ll &x){
     50         bool sign=0; char ch=nc(); x=0;
     51         for (;blank(ch);ch=nc());
     52         if (IOerror)return;
     53         if (ch=='-')sign=1,ch=nc();
     54         for (;ch>='0'&&ch<='9';ch=nc())x=x*10+ch-'0';
     55         if (sign)x=-x;
     56     }
     57     inline void read(double &x){
     58         bool sign=0; char ch=nc(); x=0;
     59         for (;blank(ch);ch=nc());
     60         if (IOerror)return;
     61         if (ch=='-')sign=1,ch=nc();
     62         for (;ch>='0'&&ch<='9';ch=nc())x=x*10+ch-'0';
     63         if (ch=='.'){
     64             double tmp=1; ch=nc();
     65             for (;ch>='0'&&ch<='9';ch=nc())tmp/=10.0,x+=tmp*(ch-'0');
     66         }
     67         if (sign)x=-x;
     68     }
     69     inline void read(char *s){
     70         char ch=nc();
     71         for (;blank(ch);ch=nc());
     72         if (IOerror)return;
     73         for (;!blank(ch)&&!IOerror;ch=nc())*s++=ch;
     74         *s=0;
     75     }
     76     inline void read(char &c){
     77         for (c=nc();blank(c);c=nc());
     78         if (IOerror){c=-1;return;}
     79     }
     80     //getchar->read
     81     inline void read1(int &x){
     82         char ch;int bo=0;x=0;
     83         for (ch=getchar();ch<'0'||ch>'9';ch=getchar())if (ch=='-')bo=1;
     84         for (;ch>='0'&&ch<='9';x=x*10+ch-'0',ch=getchar());
     85         if (bo)x=-x;
     86     }
     87     inline void read1(ll &x){
     88         char ch;int bo=0;x=0;
     89         for (ch=getchar();ch<'0'||ch>'9';ch=getchar())if (ch=='-')bo=1;
     90         for (;ch>='0'&&ch<='9';x=x*10+ch-'0',ch=getchar());
     91         if (bo)x=-x;
     92     }
     93     inline void read1(double &x){
     94         char ch;int bo=0;x=0;
     95         for (ch=getchar();ch<'0'||ch>'9';ch=getchar())if (ch=='-')bo=1;
     96         for (;ch>='0'&&ch<='9';x=x*10+ch-'0',ch=getchar());
     97         if (ch=='.'){
     98             double tmp=1;
     99             for (ch=getchar();ch>='0'&&ch<='9';tmp/=10.0,x+=tmp*(ch-'0'),ch=getchar());
    100         }
    101         if (bo)x=-x;
    102     }
    103     inline void read1(char *s){
    104         char ch=getchar();
    105         for (;blank(ch);ch=getchar());
    106         for (;!blank(ch);ch=getchar())*s++=ch;
    107         *s=0;
    108     }
    109     inline void read1(char &c){for (c=getchar();blank(c);c=getchar());}
    110     //scanf->read
    111     inline void read2(int &x){scanf("%d",&x);}
    112     inline void read2(ll &x){
    113         #ifdef _WIN32
    114             scanf("%I64d",&x);
    115         #else
    116         #ifdef __linux
    117             scanf("%lld",&x);
    118         #else
    119             puts("error:can't recognize the system!");
    120         #endif
    121         #endif
    122     }
    123     inline void read2(double &x){scanf("%lf",&x);}
    124     inline void read2(char *s){scanf("%s",s);}
    125     inline void read2(char &c){scanf(" %c",&c);}
    126     inline void readln2(char *s){gets(s);}
    127     //fwrite->write
    128     struct Ostream_fwrite{
    129         char *buf,*p1,*pend;
    130         Ostream_fwrite(){buf=new char[BUF_SIZE];p1=buf;pend=buf+BUF_SIZE;}
    131         void out(char ch){
    132             if (p1==pend){
    133                 fwrite(buf,1,BUF_SIZE,stdout);p1=buf;
    134             }
    135             *p1++=ch;
    136         }
    137         void print(int x){
    138             static char s[15],*s1;s1=s;
    139             if (!x)*s1++='0';if (x<0)out('-'),x=-x;
    140             while(x)*s1++=x%10+'0',x/=10;
    141             while(s1--!=s)out(*s1);
    142         }
    143         void println(int x){
    144             static char s[15],*s1;s1=s;
    145             if (!x)*s1++='0';if (x<0)out('-'),x=-x;
    146             while(x)*s1++=x%10+'0',x/=10;
    147             while(s1--!=s)out(*s1); out('
    ');
    148         }
    149         void print(ll x){
    150             static char s[25],*s1;s1=s;
    151             if (!x)*s1++='0';if (x<0)out('-'),x=-x;
    152             while(x)*s1++=x%10+'0',x/=10;
    153             while(s1--!=s)out(*s1);
    154         }
    155         void println(ll x){
    156             static char s[25],*s1;s1=s;
    157             if (!x)*s1++='0';if (x<0)out('-'),x=-x;
    158             while(x)*s1++=x%10+'0',x/=10;
    159             while(s1--!=s)out(*s1); out('
    ');
    160         }
    161         void print(double x,int y){
    162             static ll mul[]={1,10,100,1000,10000,100000,1000000,10000000,100000000,
    163                 1000000000,10000000000LL,100000000000LL,1000000000000LL,10000000000000LL,
    164                 100000000000000LL,1000000000000000LL,10000000000000000LL,100000000000000000LL};
    165             if (x<-1e-12)out('-'),x=-x;x*=mul[y];
    166             ll x1=(ll)floor(x); if (x-floor(x)>=0.5)++x1;
    167             ll x2=x1/mul[y],x3=x1-x2*mul[y]; print(x2);
    168             if (y>0){out('.'); for (size_t i=1;i<y&&x3*mul[i]<mul[y];out('0'),++i); print(x3);}
    169         }
    170         void println(double x,int y){print(x,y);out('
    ');}
    171         void print(char *s){while (*s)out(*s++);}
    172         void println(char *s){while (*s)out(*s++);out('
    ');}
    173         void flush(){if (p1!=buf){fwrite(buf,1,p1-buf,stdout);p1=buf;}}
    174         ~Ostream_fwrite(){flush();}
    175     }Ostream;
    176     inline void print(int x){Ostream.print(x);}
    177     inline void println(int x){Ostream.println(x);}
    178     inline void print(char x){Ostream.out(x);}
    179     inline void println(char x){Ostream.out(x);Ostream.out('
    ');}
    180     inline void print(ll x){Ostream.print(x);}
    181     inline void println(ll x){Ostream.println(x);}
    182     inline void print(double x,int y){Ostream.print(x,y);}
    183     inline void println(double x,int y){Ostream.println(x,y);}
    184     inline void print(char *s){Ostream.print(s);}
    185     inline void println(char *s){Ostream.println(s);}
    186     inline void println(){Ostream.out('
    ');}
    187     inline void flush(){Ostream.flush();}
    188     //puts->write
    189     char Out[OUT_SIZE],*o=Out;
    190     inline void print1(int x){
    191         static char buf[15];
    192         char *p1=buf;if (!x)*p1++='0';if (x<0)*o++='-',x=-x;
    193         while(x)*p1++=x%10+'0',x/=10;
    194         while(p1--!=buf)*o++=*p1;
    195     }
    196     inline void println1(int x){print1(x);*o++='
    ';}
    197     inline void print1(ll x){
    198         static char buf[25];
    199         char *p1=buf;if (!x)*p1++='0';if (x<0)*o++='-',x=-x;
    200         while(x)*p1++=x%10+'0',x/=10;
    201         while(p1--!=buf)*o++=*p1;
    202     }
    203     inline void println1(ll x){print1(x);*o++='
    ';}
    204     inline void print1(char c){*o++=c;}
    205     inline void println1(char c){*o++=c;*o++='
    ';}
    206     inline void print1(char *s){while (*s)*o++=*s++;}
    207     inline void println1(char *s){print1(s);*o++='
    ';}
    208     inline void println1(){*o++='
    ';}
    209     inline void flush1(){if (o!=Out){if (*(o-1)=='
    ')*--o=0;puts(Out);}}
    210     struct puts_write{
    211         ~puts_write(){flush1();}
    212     }_puts;
    213     inline void print2(int x){printf("%d",x);}
    214     inline void println2(int x){printf("%d
    ",x);}
    215     inline void print2(char x){printf("%c",x);}
    216     inline void println2(char x){printf("%c
    ",x);}
    217     inline void print2(ll x){
    218         #ifdef _WIN32
    219             printf("%I64d",x);
    220         #else
    221         #ifdef __linux
    222             printf("%lld",x);
    223         #else
    224             puts("error:can't recognize the system!");
    225         #endif
    226         #endif
    227     }
    228     inline void println2(ll x){print2(x);printf("
    ");}
    229     inline void println2(){printf("
    ");}
    230     #undef ll
    231     #undef OUT_SIZE
    232     #undef BUF_SIZE
    233 };
    234 using namespace fastIO;
    235 
    236 # define MX 1005
    237 /**************************/
    238 
    239 int n;
    240 vector<int> v[MX];
    241 
    242 LL cal(int a,int b,int k)
    243 {
    244     stack<int> st;
    245     LL ut=0;
    246     int tims=0; //b 用了几次
    247     int pb=0;   //指到了b 的那个位置
    248     for (int i=0;i<v[a].size();)
    249     {
    250         if (v[a][i]<=ut+1)
    251         {
    252             ut+=v[a][i];
    253             i++;
    254         }
    255         else if (tims<k)
    256         {
    257             while (pb<v[b].size()&&v[b][pb]<=ut+1) st.push(v[b][pb++]);
    258             tims++;
    259             if (st.size())
    260             {
    261                 ut+=st.top();
    262                 st.pop();
    263             }
    264             else return ut;
    265         }
    266         else return ut;
    267     }
    268     while (tims<k)
    269     {
    270         while (pb<v[b].size()&&v[b][pb]<=ut+1) st.push(v[b][pb++]);
    271         tims++;
    272         if (st.size())
    273         {
    274             ut+=st.top();
    275             st.pop();
    276         }
    277         else return ut;
    278     }
    279     return ut;
    280 }
    281 
    282 int main()
    283 {
    284     scanf("%d",&n);
    285     for (int i=1;i<=n;++i)
    286     {
    287         int m;
    288         fastIO::read(m);
    289         for (int j=1;j<=m;j++)
    290         {
    291             int x;
    292             read(x);
    293             v[i].push_back(x);
    294         }
    295         sort(v[i].begin(),v[i].end());
    296     }
    297     int t;
    298     fastIO::read(t);
    299     while (t--)
    300     {
    301         int a,b,k;
    302         fastIO::read(a); fastIO::read(b); fastIO::read(k);
    303         fastIO::println(cal(a,b,k));
    304     }
    305     return 0;
    306 }
    View Code
  • 相关阅读:
    洛谷P2294 [HNOI2005]狡猾的商人
    洛谷P2119 魔法阵
    Navicat中怎样将SQLServer的表复制到MySql中
    Electron中与Vue集成流程
    Electron中通过net的API发出HTTP请求
    Electron中实现菜单、子菜单、以及自带操作事件
    Eclipse中怎样使用ERMaster进行单表设计并导出为DDL
    Eclipse中怎样安装数据库建模工具ERMaster插件
    Eclipse中安装插件时提示:No repository found containing: osgi.bundle,org.eclipse.emf,2.8.0.v20180706-1146
    Winform中设置ZedGraph鼠标悬浮显示线上的点的坐标并自定义显示的内容
  • 原文地址:https://www.cnblogs.com/haoabcd2010/p/7475439.html
Copyright © 2011-2022 走看看