题目传送门:http://www.oj.swust.edu.cn/contest/show/1160
这是一道dp。我们假设这n个人按照水平排成一排, 可以很容易想到用dp[i][j]表示: 排到第第i个位置的人面向左边的是第j个部位的总方案数。可以有转移
dp[i][j]+=dp[i-1][k] ( 只要k和j 不发生冲突就可以转移 )。总复杂度(O(16n))
AC 代码。
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define debug
using namespace std;
const int inf = 0x3fffffff;
const int mmax = 100010;
const int mod = 522462628;
int dir[mmax];
int dp[mmax][5];
int main()
{
int n;
#ifdef debug
freopen("in.txt","r",stdin);
#endif
while(cin>>n)
{
for(int i=1;i<=n;i++)
scanf("%d",&dir[i]);
memset(dp,0,sizeof dp);
dp[1][1]=dp[1][2]=dp[1][3]=dp[1][4]=1;
for(int i=2;i<=n;i++)
{
for(int j=1;j<=4;j++)
{
for(int k=1;k<=4;k++)
{
if(k==2 && abs(j-dir[i-1])==2 )
continue;
if(j==4 && k==dir[i])
continue;
dp[i][j]+=dp[i-1][k];
dp[i][j]%=mod;
}
}
}
int ans=0;
for(int i=1;i<=4;i++)
{
ans+=dp[n][i];
ans%=mod;
}
cout<
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define debug
using namespace std;
const int mmax = 1000010;
int num[mmax],c[mmax];
int sum[50010];
bool isprime[mmax];
void pre()//nlgn的预处理方法
{
memset(isprime,1,sizeof isprime);
num[1]=0;
isprime[1]=0;
for(int i=2;i1)
cnt++;
return cnt;
}
int main()
{
int n,q;
#ifdef debug
freopen("in.txt","r",stdin);
#endif
pre();
while(cin>>n>>q&& n+q)
{
sum[0]=0;
for(int i=1;i<=n;i++)
{
int x;
scanf("%d",&x);
sum[i]=sum[i-1]+num[x];// +ff(x) 为暴力
}
while(q--)
{
int l,r;
scanf("%d %d",&l,&r);
printf("%d\n",sum[r]-sum[l-1]);
}
}
return 0;
}
#include
#include
#include
using namespace std;
#define debug
bool flag[10005];
int s[10005];
int main()
{
#ifdef debug
freopen("in.txt","r",stdin);
#endif
int n,m;
while(~scanf("%d%d",&n,&m))
{
memset(flag,false,sizeof(flag));
for(int i=0;i
/*
* Author: islands
* Created Time: 2015/8/14 14:38:28
* File Name: stand.cpp
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
/*
* Author: islands
* Created Time: 2015/8/14 14:38:28
* File Name: stand.cpp
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
/*
* Author: islands
* Created Time: 2015/8/14 14:38:28
* File Name: stand.cpp
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define debug
using namespace std;
typedef long long LL;
const int inf = 0x3fffffff;
const int mmax = 100010;
LL sum[31][2];
int Size[31];
int main()
{
#ifdef debug
freopen("in.txt","r",stdin);
#endif
int k,x;
while(cin>>k)
{
for(int i=1;i<=k;i++)
{
scanf("%d",&Size[i]);
sum[i][0]=sum[i][1]=0;
for(int j=1;j<=Size[i];j++)
{
scanf("%d",&x);
sum[i][0]+=x;
sum[i][1]+=x*j;
}
}
printf("0\n");
for(int i=2;i<=k;i++)
{
LL ans=1LL*Size[i-1]*sum[i][1]+1LL*Size[i]*sum[i-1][1];
ans+=1LL*(Size[i]+1)*Size[i]/2*sum[i-1][0];
ans+=1LL*(Size[i-1]+1)*Size[i-1]/2*sum[i][0];
printf("%lld\n",ans);
}
}
return 0;
}
/*
* Author: islands
* Created Time: 2015/8/13 21:49:13
* File Name: stand.cpp
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define debug
using namespace std;
const int inf = 0x3fffffff;
const int mmax = 300;
int Photo[mmax][mmax];
int main()
{
#ifdef debug
freopen("in.txt","r",stdin);
#endif
int n,m;
while(~scanf("%d %d",&n,&m))
{
for(int i=0;i>q;
while(q--)
{
int d,k;
cin>>d>>k;
if(d==0)
{
for(int i=0;i<(n/k);i++)
{
for(int j=0;j<(m/k);j++)
{
printf("%d%c",Photo[i*k][j*k],(j==(m/k)-1)?'\n':' ');
}
}
}
else
{
for(int i=0;i
求区间内最大值的位置,取最靠左的那个的位置。单点修改。
思路:用线段树维护区间内的最大值和最大值最靠左的位置,记录2个值,一个记录最大值,另一个几率对应位置。实际上只用开一个值,只用记录位子即可,因为位置包含着最大值。
/*
* Author: islands
* Created Time: 2015/8/14 14:38:28
* File Name: stand.cpp
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define debug
using namespace std;
const int inf = 0x3fffffff;
const int mmax = 100010;
int A[mmax];
struct node
{
int l,r;
int pos,max_val;
int mid()
{
return (l+r)>>1;
}
}T[4*mmax];
void push_up(node &fa,node &ls,node& rs)
{
fa.l=ls.l,fa.r=rs.r;
fa.max_val=max(ls.max_val,rs.max_val);
if(fa.max_val==ls.max_val)
{
fa.pos=ls.pos;
return ;
}
fa.pos=rs.pos;
}
void build(int id,int l,int r)
{
T[id].l=l,T[id].r=r;
if(l==r)
{
T[id].pos=l;
T[id].max_val=A[l];
return ;
}
int mid=T[id].mid();
build(id<<1,l,mid);
build(id<<1|1,mid+1,r);
push_up(T[id],T[id<<1],T[id<<1|1]);
}
void update(int id,int pos,int val)
{
if(T[id].l==T[id].r)
{
T[id].max_val=val;
return ;
}
int mid=T[id].mid();
if(mid>=pos)
update(id<<1,pos,val);
else
update(id<<1|1,pos,val);
push_up(T[id],T[id<<1],T[id<<1|1]);
}
node query(int id,int l,int r)
{
if(l<= T[id].l && T[id].r <=r)
return T[id];
int mid=T[id].mid();
node tmp[3];
int t=0;
if(mid>=l)
tmp[1]=query(id<<1,l,r),t++;
if(mid>t;
while(t--)
{
scanf("%d %d",&n,&q);
for(int i=1;i<=n;i++)
scanf("%d",&A[i]);
build(1,1,n);
while(q--)
{
scanf("%d %d %d",&op,&a,&b);
if(op==1)
{
node ans=query(1,a,b);
printf("%d\n",ans.pos);
}
else
update(1,a,b);
}
}
return 0;
}