Problem Description
Let us define a sequence as below
⎧⎩⎨⎪⎪⎪⎪⎪⎪F1F2Fn===ABC⋅Fn−2+D⋅Fn−1+⌊Pn⌋
Your job is simple, for each task, you should output Fn module 109+7.
Input
The first line has only one integer T, indicates the number of tasks.
Then, for the next T lines, each line consists of 6 integers, A , B, C, D, P, n.
1≤T≤200≤A,B,C,D≤1091≤P,n≤109
Sample Input
2 3 3 2 1 3 5 3 2 2 2 1 4
Sample Output
36 24
加上⌊P/n⌋就需要分块讨论使用矩阵快速幂。。
若P=20,当前取值为 i=11,则j=P/(P/i)=20;则区间[11,20]是共同的p/i
这个题需要考虑区间范围最大只能到n 因此 j=min(n,p/(p/i));
知道区间的范围,用矩阵快速幂就能求解。
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<cmath>
#include<deque>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int M = 1e5 + 10;
int t;
int n,k;
struct node
{
int id;
ll num;
}a[6][M],b[6][M];
ll ans[6];
int kp[6];
int vis[M];
bool cmp(node a,node b)
{
return a.num<b.num;
}
namespace In {
# define In_Len 2000000
static std :: streambuf *fb ( std :: cin.rdbuf ( ) ) ;
static char buf [In_Len], *ss ( 0 ), *tt ( 0 ) ;
# define pick( ) ( (ss == tt) ? ( tt = buf + fb -> sgetn ( ss = buf, In_Len ), ((ss == tt) ? -1 : *(ss ++)) ) :*(ss ++) )
inline char getc ( ) { register char c; while ( isspace ( c = pick ( ) ) ) ; return c ; }
inline int read ( ) {
register int x, c ;
bool opt ( 1 ) ;
while ( isspace ( c = pick ( ) ) && ( c ^ -1 ) ) ;
if ( c == 45 ) c = pick ( ), opt = 0 ;
for ( x = -48 + c ; isdigit ( c = pick ( ) ) ; ( x *= 10 ) += c - 48 ) ;
return opt ? x : -x ;
}
# undef pick
# undef In_Len
}
using namespace In;
namespace Out {
# define Out_Len 2000000
std :: streambuf *fb ( std :: cout.rdbuf ( ) ) ;
char buf [Out_Len], *ss ( buf ), *tt ( buf + Out_Len ) ;
# define echo( c ) ( (ss == tt) ? ( fb -> sputn ( ss = buf, Out_Len ), *ss ++ = c ) : ( *ss ++ = c ) )
inline void putc ( char c ) { echo ( c ) ; }
inline void print ( register int x ) {
static int st [30], tp ( 0 ) ;
if ( ! x ) { echo ( 48 ) ; return ; }
if ( x < 0 ) { echo ( 45 ) ; x = -x ; }
while ( x ) st [++ tp] = x % 10 | 48, x /= 10 ;
while ( tp ) { echo ( st [tp] ) ; -- tp ; }
}
inline void flush ( ) { fb -> sputn ( buf, ss - buf ) ; }
# undef echo
# undef Out_Len
}
using namespace Out;
int main()
{
scanf("%d",&t);
while(t--)
{
n=read();
k=read();
//scanf("%d%d",&n,&k);
for(int i=0;i<k;i++)
ans[i]=read();
for(int i=0;i<n;i++)
{
for(int j=0;j<k;j++)
{
a[j][i].num=read();
a[j][i].id=i;
}
for(int j=0;j<k;j++)
{
b[j][i].num=read();
b[j][i].id=i;
}
}
memset(vis,0,sizeof(vis));
for(int i=0;i<k;i++)
sort(a[i],a[i]+n,cmp);
int cnt=0;
memset(kp,0,sizeof(kp));
while(1)
{
int ok=cnt;
for(int i=0;i<k;i++)
{
while(kp[i]<n && a[i][kp[i]].num<=ans[i])
{
vis[a[i][kp[i]].id]++;
if(vis[a[i][kp[i]].id]==k)
{
cnt++;
for(int kk=0;kk<k;kk++)
ans[kk]+=b[kk][a[i][kp[i]].id].num;
}
kp[i]++;
}
}
if(ok==cnt)
break;
}
printf("%d\n",cnt);
for(int i=0;i<k;i++)
{
printf("%lld%c",ans[i],i==k-1?'\n':' ');
}
}
return 0;
}