20180625小测

T1:


最优解显然是选择一个区间。我们枚举右端点,显然左端点单调不减。
写个分治就能AC啦(话说为什么我分析出单调性后连分治都想不到)。
考场44分代码:

 1 #pragma GCC optimize("Ofast")
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cctype>
 5 typedef long long int lli;
 6 using namespace std;
 7 const int maxe=1e6+1e2,maxn=1e5,maxl=20;
 8 // I am a sb and I can't solve any problem, although all over the world has solved T1.
 9 // Compilation technology is well developed, we don't need to support it.
10 
11 int n,m;
12 
13 struct RMQ {
14     struct Array {
15         int dat[maxe][maxl];
16         inline int* operator () (const int &i,const int &j) { // i is kind , j is pos .
17             return dat[n*(i-1)+j];
18         }
19     }arr;
20     int Log[maxn];
21 
22     inline void init() {
23         for(int i=2;i<=n;i++) Log[i] = Log[i>>1] + 1;
24         for(int i=1;i<=m;i++) for(int k=1;k<=Log[n];k++) for(int j=1;j<=n;j++)
25             arr(i,j)[k] = max( arr(i,j)[k-1] , arr(i,j+(1<<(k-1)))[k-1] );
26     }
27     inline int query(int k,int l,int r) {
28         const int Lo = Log[r-l+1];
29         return max( arr(k,l)[Lo] , arr(k,r-(1<<Lo)+1)[Lo] );
30     }
31 }RMQ;
32 
33 lli su[maxn],f[maxn],ans;
34 
35 inline char nextchar() {
36     static const int BS = 1 << 21;
37     static char buf[BS],*st,*ed;
38     if( st == ed ) ed = buf + fread(st=buf,1,BS,stdin);
39     return st == ed ? -1 : *st++;
40 }
41 inline int getint() {
42     int ret = 0 , ch;
43     while( !isdigit(ch=nextchar()) ) ;
44     do ret = ret * 10 + ch - '0'; while( isdigit(ch=nextchar()) );
45     return ret;
46 }
47 int main() {
48     n = getint() , m = getint();
49     for(int i=2;i<=n;i++) su[i] = su[i-1] + getint();
50     for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) *RMQ.arr(j,i) = getint();
51     RMQ.init();
52     for(int r=n,l=n;r;r--) {
53         l = min( l , r );
54         for(int j=l;j;j--) {
55             f[j] = su[j] - su[r];
56             for(int k=1;k<=m;k++) f[j] += RMQ.query(k,j,r);
57             if( f[j] >= f[l] ) l = j;
58         }
59         ans = max( ans , f[l] );
60     }
61     printf("%lld\n",ans);
62     return 0;
63 }
View Code

正解代码:

 1 #pragma GCC optimize("Ofast")
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cctype>
 5 typedef long long int lli;
 6 using namespace std;
 7 const int maxe=1e6+1e5+1e2,maxn=1e5+1e2,maxl=20;
 8 const lli inf=0x3f3f3f3f3f3f3f3fll;
 9 
10 int n,m;
11 
12 struct RMQ {
13     struct Array {
14         int dat[maxe][maxl];
15         inline int* operator () (const int &i,const int &j) { // i is kind , j is pos .
16             return dat[n*(i-1)+j];
17         }
18     }arr;
19     int Log[maxn];
20 
21     inline void init() {
22         for(int i=2;i<=n;i++) Log[i] = Log[i>>1] + 1;
23         for(int i=1;i<=m;i++) for(int k=1;k<=Log[n];k++) for(int j=1;j<=n;j++)
24             arr(i,j)[k] = max( arr(i,j)[k-1] , arr(i,j+(1<<(k-1)))[k-1] );
25     }
26     inline int query(int k,int l,int r) {
27         const int Lo = Log[r-l+1];
28         return max( arr(k,l)[Lo] , arr(k,r-(1<<Lo)+1)[Lo] );
29     }
30 }RMQ;
31 
32 lli su[maxn],f[maxn],ans;
33 
34 inline lli calc(int ll,int rr) {
35     if( ll > rr ) return -inf;
36     lli ret = su[ll] - su[rr];
37     for(int i=1;i<=m;i++) ret += RMQ.query(i,ll,rr);
38     return ret;
39 }
40 inline void solve(int l_l,int l_r,int r_l,int r_r) {
41     if( r_l == r_r ) {
42         for(int i=l_l;i<=l_r;i++) ans = max( ans , calc(i,r_l) );
43         return;
44     } const int r_mid = ( r_l + r_r ) >> 1;
45     int l_mid = l_l; f[l_l] = calc(l_l,r_mid);
46     for(int i=l_l;i<=l_r;i++) if( ( f[i] = calc(i,r_mid) ) > f[l_mid] ) l_mid = i;
47     ans = max( ans , f[l_mid] );
48     solve(l_l,l_mid,r_l,r_mid) , solve(l_mid,l_r,r_mid+1,r_r);
49 }
50 
51 inline char nextchar() {
52     static const int BS = 1 << 21;
53     static char buf[BS],*st,*ed;
54     if( st == ed ) ed = buf + fread(st=buf,1,BS,stdin);
55     return st == ed ? -1 : *st++;
56 }
57 inline int getint() {
58     int ret = 0 , ch;
59     while( !isdigit(ch=nextchar()) ) ;
60     do ret = ret * 10 + ch - '0'; while( isdigit(ch=nextchar()) );
61     return ret;
62 }
63 
64 int main() {
65     n = getint() , m = getint();
66     for(int i=2;i<=n;i++) su[i] = su[i-1] + getint();
67     for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) *RMQ.arr(j,i) = getint();
68     RMQ.init() , solve(1,n,1,n);
69     printf("%lld\n",ans);
70     return 0;
71 }
View Code

 


T2:


暴力高斯消元大家都会。
考虑我们把图按照与原点的曼哈顿距离分层,显然i层的变量只跟i-1层和i+1层有关。
我们能从外层向内层带入,用i,i+1,i+2三层的方程,高斯消元,用第i层表示第i+1层的方程。
然后在继续迭代(i-1,i,i+1)层。后来写这个代码的时候我已经十分混乱了......
考场45分代码:

 1 #pragma GCC optimize("Ofast")
 2 #include<cstdio>
 3 #include<algorithm>
 4 typedef long long int lli;
 5 const int maxn=31,maxe=3e3+1e1;
 6 const int mod=1e9+7;
 7 
 8 inline int sub(const int &x,const int &y) {
 9     const int ret = x - y;
10     return ret < 0 ? ret + mod : ret;
11 }
12 inline int mul(const int &x,const int &y) {
13     return (lli) x * y % mod;
14 }
15 inline void adde(int &dst,const int &x) {
16     if( ( dst += x ) >= mod ) dst -= mod;
17 }
18 inline void sube(int &dst,const int &x) {
19     if( ( dst -= x ) < 0 ) dst += mod;
20 }
21 inline void mule(int &dst,const int &x) {
22     dst = (lli) dst * x % mod;
23 }
24 inline int fastpow(int base,int tim) {
25     int ret = 1;
26     while(tim) {
27         if( tim & 1 ) mule(ret,base);
28         if( tim >>= 1 ) mule(base,base);
29     }
30     return ret;
31 }
32 
33 int dat[maxe][maxe];
34 int n,r;
35 
36 struct Array {
37     int dat[maxe];
38     inline int& operator () (int x,int y) {
39         x += r , y += r;
40         return dat[x*(r*2+1)+y];
41     }
42 }id;
43 
44 inline int gid(int x,int y) {
45     if( x < -r || x > r || y < -r || y > r ) return n;
46     return id(x,y);
47 }
48 
49 
50 inline bool inside(int x,int y) {
51     return x * x + y * y <= r * r;
52 }
53 
54 inline void gauss() {
55     for(int i=1,pos;i<=n;i++) {
56         pos = -1;
57         for(int j=i;j<=n;j++) if( dat[j][i] ) { pos = j; break; }
58         if( !~pos ) continue;
59         if( pos != i ) {
60             for(int k=1;k<=n+1;k++) std::swap(dat[pos][k],dat[i][k]);
61             pos = i;
62         }
63         const int inv = fastpow(dat[i][i],mod-2);
64         for(int k=1;k<=n+1;k++) mule(dat[i][k],inv);
65         for(int j=1;j<=n;j++) if( i != j && dat[j][i] ) {
66             const int m = dat[j][i];
67             for(int k=1;k<=n+1;k++) sube(dat[j][k],mul(m,dat[i][k]));
68         }
69     }
70 }
71 
72 const int dx[]={1,0,-1,0},dy[]={0,1,0,-1};
73 int in[4],su;
74 
75 inline void build() {
76     for(int i=-r;i<=r;i++) for(int j=-r;j<=r;j++) if( inside(i,j) ) id(i,j) = ++n;
77     ++n; for(int i=-r;i<=r;i++) for(int j=-r;j<=r;j++) if( !inside(i,j) ) id(i,j) = n;
78     for(int i=-r;i<=r;i++) for(int j=-r;j<=r;j++) if( inside(i,j) ) {
79         for(int k=0;k<4;k++) {
80             const int sx = i + dx[k] , sy = j + dy[k];
81             adde(dat[id(i,j)][gid(sx,sy)],sub(0,in[k]));
82         }
83         dat[id(i,j)][id(i,j)] = 1 , dat[id(i,j)][n+1] = 1;
84     }
85     dat[n][n] = 1;
86 }
87 
88 int main() {
89     scanf("%d",&r);
90     for(int i=0;i<4;i++) scanf("%d",in+i) , adde(su,in[i]);
91     const int inv = fastpow(su,mod-2);
92     for(int i=0;i<4;i++) mule(in[i],inv);
93     build() , gauss() , printf("%d\n",dat[id(0,0)][n+1]);
94     return 0;
95 }
View Code

正解代码:

  1 #pragma GCC optimize("Ofast")
  2 #include<iostream>
  3 #include<cstdio>
  4 #include<cstring>
  5 #include<algorithm>
  6 #include<vector>
  7 #include<cstdlib>
  8 #define debug cout
  9 using namespace std;
 10 typedef long long int lli;
 11 const int maxn=1e2+1e1;
 12 const int mod=1e9+7;
 13 const int dx[]={1,0,-1,0},dy[]={0,1,0,-1};
 14 
 15 inline int sub(const int &x,const int &y) {
 16     const int ret = x - y;
 17     return ret < 0 ? ret + mod : ret;
 18 }
 19 inline int mul(const int &x,const int &y) {
 20     return (lli) x * y % mod;
 21 }
 22 inline void adde(int &dst,const int &x) {
 23     if( ( dst += x ) >= mod ) dst -= mod;
 24 }
 25 inline void sube(int &dst,const int &x) {
 26     if( ( dst -= x ) < 0 ) dst += mod;
 27 }
 28 inline void mule(int &dst,const int &x) {
 29     dst = (lli) dst * x % mod;
 30 }
 31 inline int fastpow(int base,int tim) {
 32     int ret = 1;
 33     while(tim) {
 34         if( tim & 1 ) mule(ret,base);
 35         if( tim >>= 1 ) mule(base,base);
 36     }
 37     return ret;
 38 }
 39 
 40 int dat[maxn<<3][maxn<<3];
 41 bool isOutside[maxn<<3];
 42 int at[maxn<<3];
 43 
 44 inline void gauss(int n,int es) { // n is number of xs , es is number of equations .
 45     for(int i=1,pos,used=0;i<=n;i++) if( isOutside[i] ) {
 46         pos = -1;
 47         for(int j=++used;j<=es;j++) if( dat[j][i] ) { pos = j; break; }
 48         if( !~pos ) continue;
 49         if( pos != used ) {
 50             for(int k=0;k<=n;k++) std::swap(dat[pos][k],dat[used][k]);
 51             pos = used;
 52         } at[i] = used;
 53         const int inv = fastpow(dat[used][i],mod-2);
 54         for(int k=0;k<=n;k++) mule(dat[used][k],inv);
 55         for(int j=1;j<=es;j++) if( used != j && dat[j][i] ) {
 56             const int m = dat[j][i];
 57             for(int k=0;k<=n;k++) sube(dat[j][k],mul(m,dat[used][k]));
 58         }
 59     }
 60 }
 61 
 62 struct NamePool {
 63     int stk[maxn<<3],top;
 64     inline void deleteName(int x) { stk[++top] = x; }
 65     inline int newName() { return stk[top--]; }
 66     NamePool() { for(int i=(maxn<<2)-1;i;i--) deleteName(i); }
 67     inline int usedSize() { return (maxn<<2) - 1 - top; }
 68 }np;
 69 
 70 int id[maxn][maxn];
 71 int tmp[maxn][maxn][maxn<<3]; // temp equations .
 72 int in[4],su,r;
 73 const int FS = 800;
 74 
 75 struct Point { int x,y; };
 76 vector<Point> ps[maxn<<2];
 77 
 78 inline void newLevel(const vector<Point> &ps) {
 79     for(unsigned i=0;i<ps.size();i++) id[ps[i].x][ps[i].y] = np.newName();
 80 }
 81 inline void removeLevel(const vector<Point> &ps) {
 82     for(unsigned i=ps.size()-1;~i;i--) np.deleteName(id[ps[i].x][ps[i].y]);
 83 }
 84 inline int dis(int x,int y) {
 85     return abs(r-x) + abs(r-y);
 86 }
 87 inline void buildLevel(const vector<Point> &ps) { // build this level , and copy tmp equations .
 88     memset(dat,0,sizeof(dat));
 89     int cnt = 0;
 90     for(unsigned i=0;i<ps.size();i++) {
 91         const int cc = id[ps[i].x][ps[i].y]; ++cnt;
 92         for(int j=0;j<4;j++) {
 93             const int tx = ps[i].x + dx[j] , ty = ps[i].y + dy[j];
 94             if( tx < 0 || ty < 0 ) continue;
 95             if( dis(tx,ty) > dis(ps[i].x,ps[i].y) ) {
 96                 const int m = in[j];
 97                 adde(dat[cnt][0],mul(m,tmp[tx][ty][0]));
 98                 for(int j=1;j<=FS;j++) sube(dat[cnt][j],mul(m,tmp[tx][ty][j]));
 99             } else adde(dat[cnt][id[tx][ty]],sub(0,in[j]));
100         }
101         adde(dat[cnt][cc],1) , adde(dat[cnt][0],1);
102     }
103 }
104 inline void markLevel(const vector<Point> &ps,const bool &v) {
105     for(unsigned i=0;i<ps.size();i++) isOutside[id[ps[i].x][ps[i].y]] = v;
106 }
107 inline void storeLevel(const vector<Point> ps,int n) {
108     for(unsigned i=0;i<ps.size();i++) {
109         const int pos = at[id[ps[i].x][ps[i].y]];
110         tmp[ps[i].x][ps[i].y][0] = dat[pos][0];
111         for(int j=1;j<=n;j++) if( j != id[ps[i].x][ps[i].y] )
112             tmp[ps[i].x][ps[i].y][j] = sub(0,dat[pos][j]);
113     }
114 }
115 inline void trans(int lev) { // level is new outside level .
116     newLevel(ps[lev-1]) , buildLevel(ps[lev]) , markLevel(ps[lev],1);
117     gauss(FS,ps[lev].size()) , storeLevel(ps[lev],FS);
118     markLevel(ps[lev],0) , removeLevel(ps[lev]);
119 }
120 inline int calcCent() {
121     int sul = 1 , sur = 1;
122     for(int i=0;i<4;i++) {
123         const int tx = r + dx[i] , ty = r + dy[i];
124         sube(sul,mul(tmp[tx][ty][id[r][r]],in[i])) , adde(sur,mul(tmp[tx][ty][0],in[i]));
125     }
126     return mul(sur,fastpow(sul,mod-2));
127 }
128 
129 inline bool inside(int x,int y) {
130     return (r-x)*(r-x) + (r-y)*(r-y) <= r * r;
131 }
132 
133 int main() {
134     scanf("%d",&r);
135     for(int i=0;i<4;i++) scanf("%d",in+i) , adde(su,in[i]);
136     const int inv = fastpow(su,mod-2);
137     for(int i=0;i<4;i++) mule(in[i],inv);
138     for(int i=0;i<=r<<1;i++)
139         for(int j=0;j<=r<<1;j++)
140             if( inside(i,j) ) ps[dis(i,j)].push_back((Point){i,j});
141     for(int i=r<<1,fir=1;i;i--) if( ps[i].size() ) {
142         if(fir) newLevel(ps[i]) , fir = 0;
143         trans(i);
144     }
145     printf("%d\n",calcCent());
146     return 0;
147 }
View Code

 


T3:


找规矩神仙题,我只会dfs,还是WA的。
题解:

考场30分代码:

 1 #include<cstdio>
 2 #include<utility>
 3 #include<queue>
 4 #include<cctype>
 5 #define bool unsigned char
 6 typedef std::pair<int,int> pii;
 7 using namespace std;
 8 const int maxn=5e2+1e1;
 9 
10 bool in[maxn][maxn];
11 int n,m,ans;
12 queue<pii> q;
13 
14 inline void update(int x,int y) {
15     for(int i=1;i<=n;i++) if( in[y][i] && !in[i][x] ) in[i][x] = 1 , q.push(make_pair(i,x));
16 }
17 
18 inline char nextchar() {
19     static const int BS = 1 << 20;
20     static char buf[BS],*st,*ed;
21     if( st == ed ) ed = buf + fread(st=buf,1,BS,stdin);
22     return st == ed ? -1 : *st++;
23 }
24 inline int getint() {
25     int ret = 0 , ch;
26     while( !isdigit(ch=nextchar()) ) ;
27     do ret = ret * 10 + ch - '0'; while( isdigit(ch=nextchar()) );
28     return ret;
29 }
30 
31 int main() {
32     n = getint() , m = getint();
33     for(int i=1,a,b;i<=m;i++) a = getint() , b = getint() , in[a][b] = 1 , q.push(make_pair(a,b));
34     while( q.size() ) update(q.front().first,q.front().second) , q.pop();
35     for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) ans += in[i][j];
36     printf("%d\n",ans);
37     return 0;
38 }
View Code

正解代码:

 1 #include<cstdio>
 2 #include<cstring>
 3 typedef long long int lli;
 4 const int maxn=1e5+1e2;
 5 
 6 int s[maxn],t[maxn<<1],nxt[maxn<<1],mrk[maxn];
 7 bool vis[maxn],fail;
 8 int cnt[3],ecnt;
 9 
10 inline void addedge(int from,int to) {
11     static int cnt;
12     t[++cnt] = to , nxt[cnt] = s[from] , s[from] = cnt;
13 }
14 inline void dfs(int pos,int col) {
15     static const int ne[]={1,2,0},pr[]={2,0,1};
16     if( vis[pos] ) return void(fail |= col != mrk[pos]);
17     vis[pos] = 1 , ++cnt[mrk[pos]=col];
18     for(int at=s[pos];at;at=nxt[at]) ++ecnt , dfs(t[at],(at&1)?ne[col]:pr[col]);
19 }
20 
21 int main() {
22     static int n,m;
23     static lli ans;
24     scanf("%d%d",&n,&m);
25     for(int i=1,a,b;i<=m;i++) scanf("%d%d",&a,&b) , addedge(a,b) , addedge(b,a);
26     for(int i=1;i<=n;i++) if( !vis[i] ) {
27         memset(cnt,0,sizeof(cnt)) , ecnt = fail = 0 , dfs(i,0);
28         if(fail) ans += (lli) ( cnt[0] + cnt[1] + cnt[2] ) * ( cnt[0] + cnt[1] + cnt[2] );
29         else if( !cnt[0] || !cnt[1] || !cnt[2] ) ans += ecnt >> 1;
30         else ans += (lli) cnt[0] * cnt[1] + (lli) cnt[1] * cnt[2] + (lli) cnt[2] * cnt[0];
31     }
32     printf("%lld\n",ans);
33     return 0;
34 }
View Code

 


为什么活着本身,要顾忌那么多的事情?
感觉活下去,好累......

posted @ 2018-06-25 21:55  Cmd2001  阅读(297)  评论(0编辑  收藏  举报