GuGuFishtion (hdu 6390 莫比乌斯反演)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6390
Sequence(hdu 6395 分段矩阵快速幂)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6395
比赛完之后再看这道题,其实也没有什么。。。
这道题最关键的就是怎么快速的分段
其实这也是非常常见的手法,在莫比乌斯反演的裸题以及杜教筛什么的都有:
就是在
这段区间内,
的值是一样的,而且只有
,我觉得这也是杜教筛能够做到
的原因吧
#include"bits/stdc++.h"
using namespace std;
typedef long long LL;
const int MOD=1e9+7;
struct Matrix
{
int n;
LL a[3][3];
Matrix (int n):n(n)
{
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)a[i][j]=0;
}
};
Matrix operator*(Matrix A,Matrix B)
{
int n=A.n;
Matrix res(n);
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
for(int k=0;k<n;k++)
{
res.a[i][j]+=A.a[i][k]*B.a[k][j];
res.a[i][j]%=MOD;
}
return res;
}
Matrix operator^(Matrix A,int n)
{
Matrix res(A.n),base=A;
for(int i=0;i<A.n;i++)res.a[i][i]=1;
while(n>0)
{
if(n&1)res=res*base;
base=base*base;
n>>=1;
}
return res;
}
int main()
{
int T;
cin>>T;
LL A,B,C,D,P,N;
LL Fn,Fn_1,FF,fn_1,fn_2,ff;
while(T--)
{
cin>>A>>B>>C>>D>>P>>N;
Matrix BASE(3);
BASE.a[0][0]=D;
BASE.a[0][1]=C;
BASE.a[0][2]=BASE.a[1][0]=BASE.a[2][2]=1;
Fn=B,Fn_1=A;
if(N==1)cout<<A<<endl;
else if(N==2)cout<<B<<endl;
else
{
for(int i=3,j;i<=N;i=j+1)
{
j=P/i==0?N:min(N,P/(P/i)); //这个就是关键的那句,[i,j]这一段区间的值是一样的
fn_1=Fn;
fn_2=Fn_1;
ff=P/i;
Matrix base=BASE;
base=base^(j-i+1);
Fn=base.a[0][0]*fn_1%MOD+base.a[0][1]*fn_2%MOD+base.a[0][2]*ff%MOD;
Fn_1=base.a[1][0]*fn_1%MOD+base.a[1][1]*fn_2%MOD+base.a[1][2]*ff%MOD;
}
cout<<Fn%MOD<<endl;
}
}
}
Swordsman(hdu 6396)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6396
题意:就是说有
个怪,最多有
种属性,自己也有
种属性,要在自己的每种属性都大于怪的每种属性的时候,就阔以把怪杀死,并且自己的属性还会得到对应的提升
问:最多能杀多少怪,以及最后自己的每个属性的值是多少?
参考博客:昨天看的今天写的。。。然后就没找到这位童鞋的博客T_T
这道题我参考的这位童鞋的思路感觉非常好懂:
就是先把每个属性从小到大排序,把比自己小的属性先记录下来,用一个
表示第
个怪物记录了多少属性,然后在看如果某个怪物的
达到了
个,那么就把这个怪物吃了就行了
然后这道题还非要输入挂,于是又从那位童鞋那里得到了一个优秀的输入挂
原来以前的 getchar 那种挂是假的挂啊,,,我才知道
#include"bits/stdc++.h"
#define out(x) cout<<#x<<"="<<x
#define C(n,m) ((long long)fac[(n)]*inv[(m)]%MOD*inv[(n)-(m)]%MOD)
using namespace std;
typedef long long LL;
const int maxn=1e5+5;
const int MOD=1e9+7;
//优秀的输入挂
namespace fastIO {
#define BUF_SIZE 100000
//fread -> read
bool IOerror = 0;
inline char nc() {
static char buf[BUF_SIZE], *p1 = buf + BUF_SIZE, *pend = buf + BUF_SIZE;
if(p1 == pend) {
p1 = buf;
pend = buf + fread(buf, 1, BUF_SIZE, stdin);
if(pend == p1) {
IOerror = 1;
return -1;
}
}
return *p1++;
}
inline bool blank(char ch) {
return ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t';
}
inline void read(int &x) {
char ch;
while(blank(ch = nc()));
if(IOerror) return;
for(x = ch - '0'; (ch = nc()) >= '0' && ch <= '9'; x = x * 10 + ch - '0');
}
#undef BUF_SIZE
};
//using namespace fastIO;
int N,K;
struct AAA
{
int v,id;
bool operator<(const AAA &t)const
{
return v<t.v;
}
};
AAA a[6][maxn],b[6][maxn];
int now[6];
int sum[maxn];
int main()
{
int T;
cin>>T;
while(T--)
{
fastIO::read(N);
fastIO::read(K);
for(int i=1;i<=K;i++)fastIO::read(now[i]);
for(int i=1;i<=N;i++)
{
sum[i]=0;
for(int k=1;k<=K;k++)fastIO::read(a[k][i].v),a[k][i].id=i;
for(int k=1;k<=K;k++)fastIO::read(b[k][i].v),b[k][i].id=i;
}
for(int i=1;i<=K;i++)sort(a[i]+1,a[i]+1+N);
int pos[6]={1,1,1,1,1,1};//记录每次处理到哪里了
int cnt=0;
while(1)
{
int flag=0;
for(int i=1;i<=K;i++)
{
for(int j=pos[i];j<=N;j++)
{
if(a[i][j].v<=now[i])
{
int id=a[i][j].id;
sum[id]++;
pos[i]++;
if(sum[id]==K)
{
for(int k=1;k<=K;k++)now[k]+=b[k][id].v;
cnt++;
flag=1;
}
}
else break;//不然就换下一个属性
}
}
if(flag==0)break;//找不到怪兽吃了
}
printf("%d\n",cnt);
for(int i=1;i<K;i++)printf("%d ",now[i]);
printf("%d\n",now[K]);
}
}