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;
}
View Code

 

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();
    }

}
View Code

 

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;
}
View Code

 

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;
}
View Code

 

posted @ 2020-12-05 09:42  passawayy  阅读(80)  评论(0)    收藏  举报