2019icpc yinchuan
N - Fibonacci Sequence
思路:直接输出他给的东西就可以了
B - So Easy
思路:只看他周围哪个3×3的方格就可以了,然后将三个行的操作次数设为未知数,将三个列的操作次数设为未知数,解个方程就可以了

#include<bits/stdc++.h> using namespace std; int a[1050][1050]; int main() { int n; scanf("%d",&n); int x, y; for (int i = 1; i <= n;++i) { for (int j = 1; j <= n;++j) { scanf("%d",&a[i][j]); if(a[i][j]==-1) x = i, y = j; } } int ans = a[x - 1][y] + a[x][y - 1] - a[x - 1][y - 1]; cout << ans << endl; return 0; }
I - Base62
思路:java里面的大数就解决了,打的时候还是不是很熟悉,然后浪费了很多时间。

import java.math.*; import java.util.*; public class Base62 { public static void main(String args[]) { Scanner cin=new Scanner(System.in); BigInteger cnt=BigInteger.valueOf(0); BigInteger sum=BigInteger.valueOf(0); int x=cin.nextInt(); int y=cin.nextInt(); String s=cin.next(); if(s.compareTo("0")==0) { System.out.println(0); return ; } for(int i=0;i<s.length();++i) { char a=s.charAt(i); int b; if(a>='0'&&a<='9') b=a-'0'; else if(a>='A'&&a<='Z') b=a-'A'+10; else b=a-'a'+36; sum=sum.multiply(BigInteger.valueOf(x)); sum=sum.add(BigInteger.valueOf(b)); } int[] ans=new int[1000]; int num=0; //System.out.println(sum); while(true) { if(sum.compareTo(cnt)==0) break; ans[num]=sum.mod(BigInteger.valueOf(y)).intValue(); sum=sum.divide(BigInteger.valueOf(y)); //System.out.println(sum); //System.out.println(ans[num]); num++; } for(int i=num-1;i>=0;--i) { char a='0'; if(ans[i]<=9) a+=ans[i]; else if(ans[i]<=35) { a='A'; a+=ans[i]-10; }else { a='a'; a+=ans[i]-36; } System.out.printf("%c",a); } System.out.println(); } }
G - Pot!!
题意:给你n个数,m次操作,MUL就是在l~r之间乘上一个数,MAX就是问l~r之间最多出现的次数
思路:就可以发现他的MUL的数是小于10的,那么这道题就简单很多,因为小于10的质数只有2、3、5、7,然后题目就是区间修改区间查询,那么就很容易想到线段树,用线段树去维护这4个数出现的次数,
然后用个max去维护次数出现最多的,因为是区间修改所以同样要去用个lazy数组去减少不必要的时间。做的时候把pushup想简单了,以为你下面的操作的次数不用push上去的,其实是需要的,因为你有些的查询并不一定会到那么下面,所以就需要你push上去。

#include<cstdio> #include<cmath> #include<iostream> #include<algorithm> #include<vector> #include<map> #include<stack> #include<queue> #include<cstring> #include<string> #include<set> //#include<unordered_map> using namespace std; #define rep(i,a,b) for(int i=a;i<=b;i++) #define dep(i,b,a) for(int i=b;i>=a;i--) #define m_p make_pair #define fi first #define se second #define pb push_back #define sz(x) (int)(x).size() #define pi acos(-1) #define IO ios::sync_with_stdio(false);cin.tie(0) #define io ios::sync_with_stdio(false) #define bug puts("---------bug----------") typedef long long ll; typedef pair<int,int> pii; typedef pair<ll,ll>pll; const int inf=0x3f3f3f3f; const ll INF=0x3f3f3f3f3f3f3f3f; const int eps=1e-9; inline int gcd(int a,int b){return b?gcd(b,a%b):a;} inline int lcm(int a,int b){return a*b/gcd(a,b);} inline int rd() { int x=0,f=1; char ch=getchar(); while(ch<'0'||ch>'9') { if(ch=='-') f=-1; ch=getchar();} while(ch>='0'&&ch<='9') { x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); } return x*f; } // inline char nc() {static char buf[1000000],*p1=buf,*p2=buf;return p1==p2&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2)?EOF:*p1++;} // inline void read(int &sum) {char ch=nc();sum=0;while(!(ch>='0'&&ch<='9')) ch=nc();while(ch>='0'&&ch<='9') sum=(sum<<3)+(sum<<1)+(ch-48),ch=nc();} const int maxn=1e5+50; int n, m; char op[20]; int pri[5] = {2, 3, 5, 7}; struct node { int l, r, num[4], lazy[4]; int maxx; } t[maxn << 2]; void pushup(int rt) { t[rt].maxx = max(t[rt << 1].maxx, t[rt << 1 | 1].maxx); t[rt].num[0] = max(t[rt << 1].num[0], t[rt << 1 | 1].num[0]); t[rt].num[1] = max(t[rt << 1].num[1], t[rt << 1 | 1].num[1]); t[rt].num[2] = max(t[rt << 1].num[2], t[rt << 1 | 1].num[2]); t[rt].num[3] = max(t[rt << 1].num[3], t[rt << 1 | 1].num[3]); } int get(int num[]) { int maxx = 0; rep(i, 0, 3) maxx = max(maxx, num[i]); return maxx; } void pushdown(int rt) { rep(i,0,3) { if(t[rt].lazy[i]>0) { t[rt << 1].num[i] += t[rt].lazy[i], t[rt << 1 | 1].num[i] += t[rt].lazy[i]; t[rt << 1].lazy[i] += t[rt].lazy[i], t[rt << 1 | 1].lazy[i] += t[rt].lazy[i]; t[rt].lazy[i] = 0; } } t[rt << 1].maxx = get(t[rt << 1].num), t[rt << 1 | 1].maxx = get(t[rt << 1 | 1].num); } void build(int rt,int l,int r) { t[rt].l = l, t[rt].r = r,t[rt].maxx=0; rep(i, 0, 3) t[rt].num[i] = 0, t[rt].lazy[i] = 0; if(l==r) return; int mid = (l + r) >> 1; build(rt<<1,l,mid); build(rt << 1 | 1, mid + 1, r); } void updata(int rt,int l,int r,int x) { if(t[rt].l>=l&&t[rt].r<=r) { rep(i,0,3) { while(x%pri[i]==0) { t[rt].num[i]++; t[rt].lazy[i]++; x /= pri[i]; } } t[rt].maxx = get(t[rt].num); return; } pushdown(rt); int mid = (t[rt].l + t[rt].r) >> 1; // if(r<=mid) // updata(rt << 1, l, r, x); // else if(l>mid) // updata(rt << 1 | 1, l, r, x); // else // updata(rt << 1, l, mid, x), updata(rt << 1 | 1, mid + 1, r, x); if(l<=mid) updata(rt << 1, l, r, x); if(r>mid) updata(rt << 1 | 1, l, r, x); pushup(rt); } int ask(int rt,int l,int r) { if(t[rt].l>=l&&t[rt].r<=r) { return t[rt].maxx; } int mid = (t[rt].l + t[rt].r) >> 1; int ans = 0; pushdown(rt); // if(r<=mid) // ans = max(ans, ask(rt << 1, l, r)); // else if(l>mid) // ans = max(ans, ask(rt << 1 | 1, l, r)); // else // ans = max(ask(rt << 1, l, mid), ask(rt << 1 | 1, mid + 1, r)); if(l<=mid) ans = max(ans, ask(rt << 1, l, r)); if(r>mid) ans = max(ans, ask(rt << 1 | 1, l, r)); return ans; } int main() { //IO; scanf("%d%d", &n, &m); build(1, 1, n); while(m--) { scanf("%s", op); if(op[1]=='U') { int x, y, z; x = rd(), y = rd(), z = rd(); updata(1, x, y, z); }else { int x,y; x = rd(), y = rd(); printf("ANSWER %d\n", ask(1, x, y)); } } return 0; }
K - Largest Common Submatrix
题意:给你两个n×m的矩阵,让你去寻早最大的相同的矩阵所包含的元素的个数
思路:这个很像之前做的单调栈,做的时候没想到,太蠢了。可以先计算出行的最大相同的联通,然后再用单调栈去更新列的最大联通就可以了,在更新的时候就可以把答案给算出来。你可以用个pos数组去记录b数组中的位置,然后后面再去判断和a数组当中的数是否匹配。

#include<cstdio> #include<cmath> #include<iostream> #include<algorithm> #include<vector> #include<map> #include<stack> #include<queue> #include<cstring> #include<string> #include<set> //#include<unordered_map> using namespace std; #define rep(i,a,b) for(int i=a;i<=b;i++) #define dep(i,b,a) for(int i=b;i>=a;i--) #define m_p make_pair #define fi first #define se second #define pb push_back #define sz(x) (int)(x).size() #define pi acos(-1) #define IO ios::sync_with_stdio(false);cin.tie(0) #define io ios::sync_with_stdio(false) #define bug puts("---------bug----------") typedef long long ll; typedef pair<int,int> pii; typedef pair<ll,ll>pll; const int inf=0x3f3f3f3f; const ll INF=0x3f3f3f3f3f3f3f3f; const int eps=1e-9; inline int gcd(int a,int b){return b?gcd(b,a%b):a;} inline int lcm(int a,int b){return a*b/gcd(a,b);} inline int rd() { int x=0,f=1; char ch=getchar(); while(ch<'0'||ch>'9') { if(ch=='-') f=-1; ch=getchar();} while(ch>='0'&&ch<='9') { x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); } return x*f; } // inline char nc() {static char buf[1000000],*p1=buf,*p2=buf;return p1==p2&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2)?EOF:*p1++;} // inline void read(int &sum) {char ch=nc();sum=0;while(!(ch>='0'&&ch<='9')) ch=nc();while(ch>='0'&&ch<='9') sum=(sum<<3)+(sum<<1)+(ch-48),ch=nc();} const int maxn=1e3+50; const int mann = 1e6 + 50; int a[maxn][maxn], b[maxn][maxn], n, m,len[maxn][maxn]; pii pos[mann]; stack<pii> s;//first记录他行的长度,second去记录他列能够达到多少,这里用数组去模拟栈也是一样的 //去维护一个单调递增的栈 int main() { //IO; n = rd(), m = rd(); rep(i,1,n) { rep(j, 1, m) a[i][j] = rd(); } rep(i,1,n) { rep(j, 1, m) b[i][j] = rd(),pos[b[i][j]]=m_p(i,j); } rep(i,1,n) { for (int j = 1; j <= m;) { int k = 0; pii now = pos[a[i][j]]; while(a[i][j+k]==b[now.fi][now.se+k]&&j+k<=m&&now.se+k<=m) { k++; } while(k) len[i][j++] = k--; } } int ans = 0; for (int j = 1; j <= m;++j) { for (int i = 1; i <= n;++i) { if(i!=1&&(pos[a[i][j]].fi!=pos[a[i-1][j]].fi+1||pos[a[i][j]].se!=pos[a[i-1][j]].se)) { while(!s.empty()) { ans = max(ans, (i - s.top().se) * s.top().fi); s.pop(); } // s.push(m_p(0, 0)); } int tmp=i; while(!s.empty()&&s.top().fi>=len[i][j]) { ans=max(ans,(i-s.top().se)*s.top().fi); tmp = s.top().se; s.pop(); } s.push(m_p(len[i][j], tmp)); } while(!s.empty()) { ans=max(ans,(n+1-s.top().se)*s.top().fi); s.pop(); } //s.push(m_p(0, 0)); } cout << ans << endl; return 0; }