牛客IOI周赛18-提高组(自闭,三题快速mi)

19 篇文章 0 订阅
4 篇文章 0 订阅

A,先把各个区间翻转映射为一段序列----可以发现,通过这段序列转化与原问题等价

那么可以套用快速mi的思想。。。。

直接做就好了

考场上思路假了,打表推式子推了一年。。。。。但还是没找出规律。。。。
套路见太少了

#include<bits/stdc++.h>
#define MAXN 200005
typedef long long ll;
using namespace std;

int n,m,l[15],r[15],num2[MAXN],num[MAXN],num3[MAXN];
ll k;

void poww(ll k){
	while(k){
		if(k & 1){
			for(int i = 1 ; i <= n ; i++){
				num3[i] = num[num2[i]];	
			}
			swap(num3 , num);	
		}
		//}
		for(int i = 1 ; i <= n ; i++)num3[i] = num2[num2[i]];	
		swap(num2 , num3);
		k = k >> 1;
	}
	for(int i = 1 ; i <= n ; i++)cout<<num[i]<<" ";
}

int main(){
	cin>>n>>m>>k;
	for(int i = 1 ; i <= n ; i++)num[i] = num2[i] = i;
	for(int i = 1 ; i <= m ; i++){
		cin>>l[i]>>r[i];
	}
	for(int i = 1 ; i <= m ; i++){
		for(int j = 1 ; j <= r[i] - l[i] + 1 ; j++){
			if(j + l[i] - 1 >= r[i] - j + 1)break;
			swap(num2[j + l[i] - 1] , num2[r[i] - j + 1]);
		}
	}
	poww(k);
	
}

B,考虑补集转换,至少有一个喜欢的 = 总方案 - 没有一个喜欢的
考虑计算总方案

F [ i ] F[i] F[i]为现在的数的总和为 i i i的方案数
F [ i ] = s i g a m a ( f [ i − k ] [ 1 < = k < i ] ) + 1 F[i] = sigama(f[i - k][1 <= k < i]) + 1 F[i]=sigama(f[ik][1<=k<i])+1
可得 F [ i ] = 2 i − 1 F[i] = 2 ^ {i - 1} F[i]=2i1

那么考虑没有一个喜欢的:
G [ i ] G[i] G[i]为现在的数总和为i,通过喜欢的来划分的方案数
G [ i ] = s i g a m ( G [ i − t [ k ] ] ) G[i] = sigam(G[i - t[k]]) G[i]=sigam(G[it[k]])并不好计算
巨佬说直接套矩阵快速mi就好了
然而并不会。。。。。

C、在 [ 1 , n ] [1,n] [1,n]内选出m个数,并且选出的这m个数为单峰序列的方案数

trick:遇到递增问题:考虑转换为差分

考虑选出序列的差分数组
发现前半部分: s u m > = j sum >= j sum>=j
后半部分 : s u m < j sum < j sum<j

直接转换为dp
然后推式子即可

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值