2019CCPC网络预选赛解题报告

HDU 6709 Fishing Master

来自队友:题解

HDU 6702 ^&^

/*************
题目:HDU 6702 ^&^
链接:https://vjudge.net/problem/HDU-6702
题意:给一个A,B,输出(A xor C) & (B xor C)值最小的正整数C
类型:思维
思路:输出A&B,如果A&B==0输出1即可
*************/
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define met(a,b) memset(a,b,sizeof(a))
#define ios1 ios::sync_with_stdio(false)
#define ios2 cin.tie(0);cout.tie(0)
const int maxn = 1e5+5;
const ll mod = 1e9+7;
const int inf = 0x3f3f3f3f;

int main()
{
    int t;scanf("%d",&t);
    while(t--){
        ll a,b;
        scanf("%lld%lld",&a,&b);
        if((a&b)==0) printf("1\n");
        else printf("%lld\n",a&b);
    }
    return 0;
}

HDU 6707 Shuffle Card

/*************
题目:HDU 6707 Shuffle Card
链接:https://vjudge.net/problem/HDU-6707
题意:一副牌由n张牌组成。每张卡片都是不同的,编号1到n。起初,牌序为1到n。现在有m次操作,每次抽取一个编号,将该编号的牌放到第一张牌的位置。最后输出所有操作后的卡牌的顺序。
类型:思维
思路:n和m的范围都是1e5,加起来不会爆栈,所以直接拿栈做,然后再用map维护,输出从栈顶往下每个第一次出现的编号。
*************/
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define met(a,b) memset(a,b,sizeof(a))
#define ios1 ios::sync_with_stdio(false)
#define ios2 cin.tie(0);cout.tie(0)
const int maxn = 1e5+5;
const ll mod = 1e9+7;
const int inf = 0x3f3f3f3f;

int n,t,m;
int a[maxn],num;
stack<int>sta;
map<int ,int>mp;
int main(){
    scanf("%d%d",&n,&m);
    for(int i=0;i<n;i++)scanf("%d",&a[i]);
    for(int i=n-1;i>=0;i--){sta.push(a[i]);mp[a[i]]++;} 
    for(int i=0;i<m;i++){
        scanf("%d",&num);
        sta.push(num);
    }
    while(!sta.empty()){
        int tmp=sta.top();
        sta.pop(); 
        if(mp[tmp]){
            mp[tmp]--;
            printf("%d ",tmp);
        }
    }
    return 0;
}

HDU 6708 Windows Of CCPC

/*************
题目:HDU 6708 Windows Of CCPC
链接:https://vjudge.net/problem/HDU-6708
题意:递推的模拟,每次左上角,右上角,右下角不变,左下角CCPC取反即可
类型:模拟
思路:模拟
*************/
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define met(a,b) memset(a,b,sizeof(a))
#define ios1 ios::sync_with_stdio(false)
#define ios2 cin.tie(0);cout.tie(0)
const int maxn = 1e5+5;
const ll mod = 1e9+7;
const int inf = 0x3f3f3f3f;

struct node{
    char a[1500][1500];
}x[15];

int main()
{
    ios1;ios2;
    int t;cin>>t;
    x[1].a[1][1]=x[1].a[1][2]=x[1].a[2][2]='C';
    x[1].a[2][1]='P';
    for(int i=2;i<=10;i++){
        int y=1<<(i-1);
        for(int j=1;j<=y;j++){
            for(int k=1;k<=y;k++){
                x[i].a[j][k]=x[i].a[j][k+y]=x[i].a[j+y][k+y]=x[i-1].a[j][k];
                if(x[i-1].a[j][k]=='P') x[i].a[j+y][k]='C';
                else x[i].a[j+y][k]='P';
            }
        }
    }
    while(t--){
        int k;cin>>k;
        int n=1<<k;
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                cout<<x[k].a[i][j];
            }
            cout<<endl;
        }
    }
    return 0;
}

HDU 6704 K-th occurrence

/*************
题目:HDU 6704 K-th occurrence
链接:https://vjudge.net/problem/HDU-6704
题意:一个字符串,对于每次询问,从l到r的子串在主串中第k次出现的下标是多少,不存在输出-1
类型:后缀数组+ST表+二分+主席树
思路:ST表维护后缀数组排序的ht数组(最长公共长度)的最小值,二分找出左右符合的位置,最后主席树维护后缀数组,求区间第k大
*************/
#include<bits/stdc++.h>
using namespace std;

const int maxn = 1e5+5;
char s[maxn];
int tmp[maxn],rk[maxn],ht[maxn],sa[maxn],str[maxn],st[maxn][22];

int k,n,m;
bool cmp(int i, int j)
{
	if(rk[i] != rk[j]) return rk[i] < rk[j];
	else {
		int ri = i+k<=n? rk[i+k] : -1;
		int rj = j+k<=n? rk[j+k] : -1;
		return ri<rj;
	}
}
void get_sa()
{
	for(int i=0;i<=n;i++){
		rk[i]=str[i];
		sa[i]=i;
	}
	for(k=1; k<=n; k<<=1){
		sort(sa,sa+n,cmp);
		tmp[sa[0]] = 0;
		for(int i=0;i<n;i++) tmp[sa[i+1]] = tmp[sa[i]] + (cmp(sa[i],sa[i+1])?1:0);
		for(int i=0;i<n;i++) rk[i] = tmp[i];
	}
	for(int i=n;i>0;i--) sa[i] = sa[i-1];sa[0]=n;
	int x=0;
	for(int i=0;i<=n;i++) rk[sa[i]] = i;
	for(int i=0;i<n;i++){
		if(x)x--;else x=0;
		int j=sa[rk[i]-1];
		while(str[i+x] == str[j+x]) x++;
		ht[rk[i]] = x;
	}
	//for(int i=0;i<=n;i++) cout<<"********"<<i<<" "<<sa[i]<<" "<<rk[i]<<" "<<ht[i]<<endl;
}

//st表维护后缀排序后的公共长度的最小值(rmq)
void rmq()
{
	for(int i=1;i<=n;i++) st[i][0] = ht[i];
	for(int j=1;j<22;j++){
		for(int i=1;i+(1<<j)-1<=n;i++){
			st[i][j] = min(st[i][j-1],st[i+(1<<(j-1))][j-1]);
		}
	}
}

int que_st(int l,int r)
{
	int k = (int)(log(r*1.0-l+1)/log(2.0));//int k=log2(r-l+1.0)
	return min(st[l][k],st[r-(1<<k)+1][k]);
}
//主席树维护排序后的序列,查询第k大
struct node{
	int l,r,val;
}tree[maxn*22];
int root[maxn],tot;

int update(int pre, int l, int r, int pos)
{
	int cur = ++tot;
	tree[cur] = tree[pre];
	tree[cur].val++;
	if(l == r) return cur;
	int mid = (l+r)>>1;
	if(pos <= mid) tree[cur].l = update(tree[pre].l, l, mid, pos);
	else tree[cur].r = update(tree[pre].r, mid+1, r, pos);
	return cur;
}

int query(int pl, int pr, int l, int r, int k){
	if(l == r) return l;
	int mid = (l+r)>>1;
	if(tree[tree[pr].l].val - tree[tree[pl].l].val >= k) return query(tree[pl].l, tree[pr].l, l, mid, k);
	else return query(tree[pl].r, tree[pr].r, mid+1, r, k-(tree[tree[pr].l].val - tree[tree[pl].l].val));
}

int main()
{
    int T;scanf("%d",&T);
    while(T--){
    	scanf("%d%d",&n,&m);
    	scanf("%s",s);
    	for(int i=0;i<n;i++) str[i] = s[i] - 'a' + 1;
    	str[n] = 0;
    	get_sa();
    	rmq();
    	tot = 0;
    	for(int i=1;i<=n;i++){
    		root[i] = update(root[i-1], 1, n, sa[i]+1);
		}
		while(m--){
			int l,r,k;scanf("%d%d%d",&l,&r,&k);
			int len = r-l+1;
			l = rk[l-1];
			int ll = 1, rr = l, cntl, cntr;
			while(ll <= rr){
				int mid = (ll+rr)>>1;
				int cnt = 100000;
				if(mid+1 <= l) cnt = que_st(mid+1,l);
				if(cnt >= len) cntl = mid,rr = mid - 1;
				else ll = mid + 1;
			}
			ll = l, rr = n;
			while(ll <= rr){
				int mid = (ll+rr)>>1;
				int cnt = 100000;
				if(l+1 <= mid) cnt = que_st(l+1,mid);
				if(cnt >= len) cntr =  mid, ll =  mid +1;
				else rr = mid - 1;
			}
			if(cntr-cntl+1<k) puts("-1");
			else printf("%d\n",query(root[cntl - 1], root[cntr], 1, n, k));
		}
	}
    return 0;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值