题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2243
题目大意:
给m个字符串,求长度不超过n且包括这m个字符串的字符串个数。
题目思路:
推荐博客:传送门
跟POJ 2778非常像,之前那个题是求不包括的,这里是求包括的,那非常自然就想到可以用所有的情况数减去不包括的情况数。所有的情况数就是长度为1的所有情况+长度为2的…+长度为n的,也就是26+262+...26n,对于矩阵也同样如此,矩阵的获得方法可以看我前面POJ2778的题解:传送门,接下来就是说明如何求得这个次数变大的和
这其实是一个矩阵快速幂的经典问题,对于矩阵
∣∣∣∣A011∣∣∣∣∗∣∣∣∣A011∣∣∣∣=∣∣∣∣A20A+11∣∣∣∣
如果这还不够明显,就再来一次!
∣∣∣∣A20A+11∣∣∣∣∗∣∣∣∣A011∣∣∣∣=∣∣∣∣A30A2+A+11∣∣∣∣
就是这么神奇!右上角就是我们需要的东西!矩阵要用的话,将1换成单位矩阵即可。
以下是代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)
const int MAXN=2e5+5;
const int MOD=1e9+7;
int n,num[MAXN];
struct node{
int pos,val;
}d[MAXN];
bool cmp(node a,node b){
return a.val>b.val;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
while(cin>>n){
rep(i,1,n){
d[i].pos=i;
cin>>d[i].val;
}
sort(d+1,d+n+1,cmp);
int pos=n;
rep(i,1,n)num[i]=d[i].pos*2-1;
rep(i,1,n-1){
cout<<d[i].pos*2-1<<" "<<d[i+1].pos*2-1<<endl;
}
rep(i,1,n){
int x=i+d[i].val-1;
if(x>pos){
pos=x;
num[pos]=d[i].pos*2;
cout<<d[i].pos*2<<" "<<num[pos-1]<<endl;
}
else{
cout<<d[i].pos*2<<" "<<num[x]<<endl;
if(x==pos)num[++pos]=d[i].pos*2;
}
}
}
return 0;
}
smilestruggler
发布了273 篇原创文章 · 获赞 27 · 访问量 2万+
私信
关注