2019 牛客多校 第八场
题目链接:https://ac.nowcoder.com/acm/contest/888#question 链接
A:(未解决)
题意:给出一个由01组成的矩阵,求多少个最大的(不被其他的全是1子矩阵包含)全是1的子矩阵 n*n<9e6
题解:单调队列
B:
题意:求所有子区间的完美数(区间中数的种类)之和,n <1e5
题解:方法1:求每一个数对答案的贡献,即有多少个子区间中包含这个数。
方法2:如果n个数不同的话,总数是n*(n+1)*(n+2)/6, 在减去重复的部分。
注意这里会算到long long,记得要乘1ll
#include<bits/stdc++.h> using namespace std; #define _for(i,a,b) for(int i=(a); i< (b); i++) #define _rep(i,a,b) for(int i=(a); i<=(b); i++) typedef long long ll; const int MAXN=2e5+5; int n, a[MAXN], pre[MAXN]; int main() //方法1 { cin>>n; _rep(i, 1, n) cin>>a[i]; ll ans=0; _rep(i, 1, n) { ans+=1ll*(i-pre[a[i]])*(n-i+1); pre[a[i]]=i; } cout<<ans<<endl; return 0; } /* int main() //方法2 { cin>>n; _rep(i, 1, n) cin>>a[i]; ll ans=1ll*n*(n+1)*(n+2)/6; _rep(i, 1, n) { ans-=1ll*(n-i+1)*pre[a[i]]; pre[a[i]]=i; } cout<<ans<<endl; return 0; } */
C:
题意:构造一个矩阵,满足任意俩行的内积是0,n=2^k (1<k<=10)
题解:
打表的过程由递归实现。
#include <bits/stdc++.h> using namespace std; #define _for(i,a,b) for(int i=(a); i< (b); i++) #define _rep(i,a,b) for(int i=(a); i<=(b); i++) typedef long long ll; const int MAXN=1e3+500; int n, a[MAXN][MAXN]; void dfs(int x, int y, int n, int v) { if(n==1){ a[x][y]=v; return; } dfs(x, y, n/2, v); dfs(x, y+n/2, n/2, v); dfs(x+n/2, y, n/2, v); dfs(x+n/2, y+n/2, n/2, -v); } int main() { dfs(1, 1, 1024, 1); while(cin>>n) { _rep(i,1,n) _rep(j,1,n) cout<<a[i][j]<<(j==n?"\n":" "); } return 0; }
E:(未解决)
题意:给出每条边的起点终点和cap的范围,求可以从1到n的cap的取值个数(整数)n,m<1e5, cap<1e9
题解:线段树+离散化+并查集
G:
题意:每三个相同消除,消除后自动相连,可以继续消除,求可以消除多少组。 n<1e5
题解:方法1:做一个next数组标记每一个位置前面的是什么,然后比较相连的三个。
方法2:栈模拟即可。
#include <bits/stdc++.h> using namespace std; #define _for(i,a,b) for(int i=(a); i< (b); i++) #define _rep(i,a,b) for(int i=(a); i<=(b); i++) typedef long long ll; const int MAXN=2e6+5; char a[MAXN]; int cnt[MAXN], nxt[MAXN]; int main() { cin>>a; int len=strlen(a), ans=0; for(int i=0; i<len; i++) cnt[i]=1; nxt[0]=0; for(int i=0; i<len; i++) nxt[i]=i-1; int p; for(int i=1; i<len; i++) { p=nxt[i]; if(a[i]==a[p]) { cnt[i]+=cnt[p]; if(cnt[i]>=3){ //printf("!i=%d\n", i); ans++; nxt[i+1]=nxt[nxt[p]]; //printf("!p=%d\n", p); } } } cout<<ans<<endl; return 0; }
#include <bits/stdc++.h> using namespace std; #define _for(i,a,b) for(int i=(a); i< (b); i++) #define _rep(i,a,b) for(int i=(a); i<=(b); i++) typedef long long ll; const int MAXN=1e5+5; char a[MAXN], s[MAXN]; int main() { scanf("%s", a+1); int n=strlen(a+1), ans=0, top=0; _rep(i, 1, n) { s[++top]=a[i]; if(top>=3 && s[top]==s[top-1]&&s[top-1]==s[top-2]){ ans++; top-=3; } } cout<<ans<<endl; return 0; }