zoukankan      html  css  js  c++  java
  • 181020-181021 模拟 题解

    Day1

    总体状态自认为不错....但是T1读错题了就很难受

    以后一定要看清楚所有的细节再写题 因为不一定什么细节就能改变所有的思路

    T2 Debug 70+min...其实就是细节的问题(二分边界)

    所以写代码的时候一定要考虑周全

    Think twice,code once.

    T1 backpack 60/100

    Time cost :15min

    怎么可能把算法在题面里说出来啊...

    天真的以为m<=1e6然后开心的O(a*m)结束..

    题解里面有个结论 就是体积极大的时候可以贪心选性价比最高的到一定程度

    题解用抽屉原理证了一下 这个其实考试的时候可以想成一直选到m<=1e5再做背包

    Code:

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<cmath>
     4 #include <iostream>
     5 #include<algorithm>
     6 #define rep(i,a,n) for(int i = a;i <= n;++i)
     7 #define per(i,n,a) for(int i = n;i >= a;--i)
     8 #define inf 2147483647
     9 #define ms(a,b) memset(a,b,sizeof a)
    10 using namespace std;
    11 typedef long long ll;
    12 ll read() {
    13     ll as = 0,fu = 1;
    14     char c = getchar();
    15     while(c < '0' || c > '9') {
    16     if(c == '-') fu = -1;
    17     c = getchar();
    18     }
    19     while(c >= '0' && c <= '9') {
    20     as = as * 10 + c - '0';
    21     c = getchar();
    22     }
    23     return as * fu;
    24 }
    25 //head
    26 const int N = 100005;
    27 ll n,m,maxid;
    28 ll a[105],dp[N];
    29 
    30 int main() {
    31     freopen("backpack.in","r",stdin);
    32     freopen("backpack.out","w",stdout);
    33     n = read(),m = read();
    34     rep(i,1,n) {
    35         int x = read();
    36         a[x] = max(a[x],read());
    37     }
    38     rep(x,1,100) {
    39         if(!maxid || a[x] * maxid > a[maxid] * x) maxid = x;
    40     }
    41     ll cnt = (m - 1e5) / maxid;
    42     ll ans = cnt * a[maxid];
    43     m -= cnt * maxid;
    44     dp[0] = 0;
    45     rep(i,1,100) {
    46         rep(j,i,m) {
    47             dp[j] = max(dp[j],dp[j-i]+a[i]);
    48         }
    49     }
    50     printf("%lld
    ",dp[m]+ans);
    51     return 0;
    52 }

    T2 sort 100/100

    Time cost : 130min

    写代码不注意细节...亏大了

    当时大样例要是改不过来就爆0

    思路就是首先需要看出来(或者证出来)

    最大值是前后一半

    最小值是交叉

    方案数是Catalan(因为是转化后的括号序列)

    不知道为什么不少人看不出来...之前还一起研究来着

    Catalan可以O(n)预处理O(1)做

    关键就是交叉这个需要开两个长为n的线段树分别维护奇偶位置上的值

    然后最大值就特别恶心

    (最后题解开了3棵线段树...)

    Code:

      1 #include<cstdio>
      2 #include<iostream>
      3 #include<cstring>
      4 #include<algorithm>
      5 #include<cmath>
      6 #include<queue>
      7 #include<vector>
      8 #define ms(a,b) memset(a,b,sizeof a)
      9 #define rep(i,a,n) for(int i = a;i <= n;++i)
     10 #define per(i,n,a) for(int i = n;i >= a;--i)
     11 #define inf 2147483647
     12 using namespace std;
     13 typedef long long ll;
     14 ll read() {
     15     ll as = 0,fu = 1;
     16     char c = getchar();
     17     while(c < '0' || c > '9') {
     18         if(c == '-') fu = -1;
     19         c = getchar();
     20     }
     21     while(c >= '0' && c <= '9') {
     22         as = as * 10 + c - '0';
     23         c = getchar();
     24     }
     25     return as * fu;
     26 }
     27 const int N = 1000005;
     28 const int mod = 1e9+7;
     29 //head
     30 int n;
     31 ll a[N];
     32 ll stp[N],stq[N];
     33 ll ksm(ll a,ll b,ll p) {
     34     ll tmp = 1;
     35     while(b) {
     36         if(b & 1) tmp = tmp * a % p;
     37         a = a * a % p;
     38         b >>= 1;
     39     }
     40     return tmp;
     41 }
     42 
     43 ll fac[N],inv[N];
     44 void initfac() {
     45     fac[0] = inv[0] = inv[1] = 1;
     46     rep(i,1,n<<1) fac[i] = fac[i-1] * i % mod;
     47     inv[n<<1] = ksm(fac[n<<1],mod - 2,mod);
     48     per(i,(n<<1)-1,2) inv[i] = inv[i+1] * (i+1) % mod;
     49 }
     50 
     51 ll Catalan(int n) {
     52     return fac[n<<1] * inv[n+1] % mod * inv[n] % mod;
     53 }
     54 
     55 ll p[N<<2],q[N<<2];
     56 ll addp[N<<2],addq[N<<2];
     57 #define ls t<<1
     58 #define rs t<<1|1
     59 void pup(int t) {
     60     p[t] = (p[ls] + p[rs]) % mod;
     61 }
     62 
     63 void pdown(int l,int r,int t) {
     64     if(!addp[t]) return;
     65     int m = l+r >> 1;
     66     int szl = m+1-l,szr = r-m;
     67     p[ls] = (p[ls] + addp[t] * szl) % mod;
     68     p[rs] = (p[rs] + addp[t] * szr) % mod;
     69     addp[ls] = (addp[t] + addp[ls]) % mod;
     70     addp[rs] = (addp[t] + addp[rs]) % mod;
     71     addp[t] = 0;
     72 }
     73 
     74 void qup(int t) {
     75     q[t] = (q[ls] + q[rs]) % mod;
     76 }
     77 
     78 void qdown(int l,int r,int t) {
     79     if(!addq[t]) return;
     80     int m = l+r >> 1;
     81     int szl = m+1-l,szr = r-m;
     82     q[ls] = (q[ls] + addq[t] * szl) % mod;
     83     q[rs] = (q[rs] + addq[t] * szr) % mod;
     84     addq[ls] = (addq[ls] + addq[t]);
     85     addq[rs] = (addq[rs] + addq[t]);
     86     addq[t] = 0;
     87 }
     88 
     89 void build(int l,int r,int t) {
     90     if(l == r) {
     91         p[t] = stp[l];
     92         q[t] = stq[l];
     93         return;
     94     }
     95     int m = l+r >> 1;
     96     build(l,m,ls),build(m+1,r,rs);
     97     pup(t),qup(t);
     98 }
     99 
    100 void update(int L,int R,ll c,int l,int r,int t,bool op) {
    101     if(L > R) return;
    102     if(L <= l && r <= R) {
    103         if(op) {
    104             p[t] = (p[t] + c * (r-l+1)) % mod;
    105             addp[t] = (addp[t] + c) % mod;
    106         } else {
    107             q[t] = (q[t] + c * (r-l+1)) % mod;
    108             addq[t] = (addq[t] + c) % mod;
    109         }
    110         return;
    111     }
    112     pdown(l,r,t),qdown(l,r,t);
    113     int m = l+r >> 1;
    114     if(L <= m) update(L,R,c,l,m,ls,op);
    115     if(R > m) update(L,R,c,m+1,r,rs,op);
    116     pup(t),qup(t);
    117 }
    118 
    119 ll query(int L,int R,int l,int r,int t,bool op) {
    120     if(L > R) return 0;
    121     if(L <= l && r <= R) return op ? p[t] : q[t];
    122     pdown(l,r,t),qdown(l,r,t);
    123     int m = l+r >> 1;
    124     ll ans = 0;
    125     if(L <= m) ans = (ans + query(L,R,l,m,ls,op)) % mod;
    126     if(R >  m) ans = (ans + query(L,R,m+1,r,rs,op)) % mod;
    127     return ans;
    128 }
    129 
    130 #define idx(i) (((i)+1)>>1)
    131 int main() {
    132     freopen("sort.in","r",stdin);
    133     freopen("sort.out","w",stdout);
    134     n = read();
    135     int T = read();
    136     rep(i,1,n<<1) a[i] = read();
    137     rep(i,1,n) {
    138         stp[i] = a[(i<<1)-1];
    139         stq[i] = a[i<<1];
    140     }
    141     initfac(),build(1,n,1);
    142     while(T--) {
    143         int op = read(),x = read(),y = read();
    144         if(op) {
    145             ll maxx,minn,Cat;
    146             int m = x+y >> 1;
    147             if((x & 1) == (m & 1)) {
    148                 maxx = query(idx(m+1),idx(y),1,n,1,y&1) + query(idx(m+2),idx(y-1),1,n,1,x&1);
    149                 maxx = maxx - query(idx(x),idx(m),1,n,1,x&1) - query(idx(x+1),idx(m-1),1,n,1,y&1);
    150             } else {
    151                 maxx = query(idx(m+2),idx(y),1,n,1,y&1) + query(idx(m+1),idx(y-1),1,n,1,x&1);
    152                 maxx = maxx - query(idx(x),idx(m-1),1,n,1,x&1) - query(idx(x+1),idx(m),1,n,1,y&1);
    153             }
    154             maxx = (maxx % mod + mod) % mod;
    155             minn = query(idx(x+1),idx(y),1,n,1,(y&1)) - query(idx(x),idx(y-1),1,n,1,(x&1));
    156             minn = (minn % mod + mod) % mod;
    157             Cat = Catalan(y-x+1>>1);
    158             printf("%lld %lld %lld
    ",maxx,minn,Cat);
    159         } else {
    160             ll k = read();
    161             update(idx(x),idx(y-1),k,1,n,1,(x&1));
    162             update(idx(x+1),idx(y),k,1,n,1,(y&1));
    163         }
    164     }
    165     return 0;
    166 }

    T3 digit 0/100

    超级水的dp...如果心态稳一点或者代码仔细一点说不定真能AK...

    50思路就是f[i][j]表示i位mod60余j有多少种情况( 60 == lcm(4,5,6) )

    所以f[i][j] = ∑f[i-1][l](0<=l<k) f[0][0]=0

    然后就是一个显然的矩阵乘法

    发现自己会矩阵乘法 但是每次都是线性Dp不出来....

    Code:

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #include<cmath>
     5 #include<queue>
     6 #include<vector>
     7 #define C continue
     8 #define B break
     9 #define ms(a,b) memset(a,b,sizeof a)
    10 #define rep(i,a,n) for(int i = a;i <= n;i++)
    11 #define per(i,n,a) for(int i = n;i >= a;i--)
    12 #define inf 3e10
    13 using namespace std;
    14 typedef long long ll;
    15 ll read() {
    16     ll as = 0,fu = 1;
    17     char c = getchar();
    18     while(c < '0' || c > '9') {
    19         if(c == '-') fu = -1;
    20         c = getchar();
    21     }
    22     while(c >= '0' && c <= '9') {
    23         as = as * 10 + c - '0';
    24         c = getchar();
    25     }
    26     return as * fu;
    27 }
    28 const int N = 60;
    29 const ll mod = 1e9+7;
    30 //head
    31 struct Mt {
    32     ll a[N][N];
    33     void init(bool op) {
    34         ms(a,0);
    35         rep(i,0,N-1) a[i][i] = op;
    36     }
    37     Mt operator * (const Mt &o) const {
    38         Mt tmp;tmp.init(0);
    39         rep(i,0,N-1) rep(j,0,N-1) rep(k,0,N-1) {
    40             tmp.a[i][j] = (tmp.a[i][j] + (ll)a[i][k] * o.a[k][j] % mod) % mod;
    41         }
    42         return tmp;
    43     }
    44     Mt operator ^ (ll b) const {
    45         Mt tmp;tmp.init(1);
    46         Mt t = *this;
    47         while(b) {
    48             if(b & 1) tmp = tmp * t;
    49             t = t * t;
    50             b >>= 1;
    51         }
    52         return tmp;
    53     }
    54 }str,res;
    55 bool judge(int x) {
    56     if(x % 4 == 0) return 1;
    57     if(x % 5 == 0) return 1;
    58     if(x % 6 == 0) return 1;
    59     return 0;
    60 }
    61 ll l,r,k,ans;
    62 
    63 int main() {
    64     freopen("digit.in","r",stdin);
    65     freopen("digit.out","w",stdout);
    66     l = read(),r = read(),k = read();
    67     str.init(0);
    68     rep(i,0,N-1) {
    69         rep(j,0,N-1) str.a[j][i] = k / N % mod;
    70         rep(j,0,k % N - 1) str.a[(i + j) % N][i]++;
    71     }
    72     
    73     res = str ^ r;
    74     rep(i,0,N-1)
    75         if(judge(i)) ans = (ans + res.a[i][0]) % mod;
    76     
    77     res = str ^ (l-1);
    78     rep(i,0,N-1)
    79         if(judge(i)) ans = (ans + mod - res.a[i][0]) % mod;
    80     printf("%lld
    ",ans);
    81     return 0;
    82 }

    Day2 

    三道题都不会...

    最后gangT1没gang过还交错了...

    T1 median

    其实考试的时候思路基本出来了...但是还是二分边界不熟...

    做法是先假设答案在a序列里

    二分a中的点(答案?) 可以得出如果这个点是答案那么应该在b中排第几

    如果对的话就是答案 否则就往左右跳

    Code:

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<cmath>
     4 #include <iostream>
     5 #include<algorithm>
     6 #define rep(i,a,n) for(int i = a;i <= n;++i)
     7 #define per(i,n,a) for(int i = n;i >= a;--i)
     8 #define inf 2147483647
     9 #define ms(a,b) memset(a,b,sizeof a)
    10 using namespace std;
    11 typedef long long ll;
    12 ll read() {
    13     ll as = 0,fu = 1;
    14     char c = getchar();
    15     while(c < '0' || c > '9') {
    16     if(c == '-') fu = -1;
    17     c = getchar();
    18     }
    19     while(c >= '0' && c <= '9') {
    20     as = as * 10 + c - '0';
    21     c = getchar();
    22     }
    23     return as * fu;
    24 }
    25 //head
    26 const int N = 500005;
    27 int n,m,ans;
    28 int a[N],b[N];
    29 
    30 int calc(int *a,int *b,int l1,int r1,int l2,int r2) {
    31     int Rnk = r1 - l1 + 1 + r2 - l2 + 1 >> 1,l = l1,r = r1;
    32     while(l <= r) {
    33     int m = l+r >> 1;
    34     int rnkb = Rnk - (m-l1+1) + l2;
    35     if(rnkb == l2 - 1 && Rnk == m-l1 && a[m] <= b[l2]) return a[m];
    36     else if(rnkb < l2) r = m - 1;
    37     else if(rnkb > r2) l = m + 1;
    38     else if(a[m] >= b[rnkb] && (a[m] <= b[rnkb+1] || rnkb == r2)) return a[m];
    39     else if(a[m] >= b[rnkb]) r = m-1;
    40     else l = m+1;
    41     }
    42     return 0;
    43 }
    44 
    45 
    46 int main() {
    47     freopen("median.in","r",stdin);
    48     freopen("median.out","w",stdout);
    49     n = read(),m = read();
    50     rep(i,1,n) a[i] = read();
    51     rep(i,1,n) b[i] = read();
    52     rep(i,1,m) {
    53     int op = read(); 
    54     if(op == 1) {
    55         int x = read(),y = read(),z = read();
    56         x ? b[y] = z : a[y] = z;
    57     } else {
    58         int l1 = read(),r1 = read(),l2 = read(),r2 = read();
    59         if(ans = calc(a,b,l1,r1,l2,r2)) printf("%d
    ",ans);
    60         else printf("%d
    ",calc(b,a,l2,r2,l1,r1));
    61     }
    62     }
    63     return 0;
    64 }
    65  
    > 别忘了 总有人在等着你
  • 相关阅读:
    homework2
    homework1
    软工实践个人总结
    实验 7:OpenDaylight 实验——Python 中的 REST API 调用 (选做题)
    第4次作业-结对编程之实验室程序实现
    实验 6:OpenDaylight 实验——OpenDaylight 及 Postman 实现流表下发
    实验 5:OpenFlow 协议分析和 OpenDaylight 安装
    软件工程结对作业需求分析与原型
    实验 4:Open vSwitch 实验——Mininet 中使用 OVS 命令
    实验 3:Mininet 实验——测量路径的损耗率
  • 原文地址:https://www.cnblogs.com/yuyanjiaB/p/9834025.html
Copyright © 2011-2022 走看看