http://codeforces.com/contest/1105/problem/C
题意:
给n,l,r。
一个n长的数组每个位置可以填区间l-r的值。
有多少种填法,使得数组每个位置相加的和是3的倍数
dp,
从1个数组扩展到n个数组,
dp[i][j]是加上第i个数组后,分别余0,1,2的个数。
#include
using namespace std;
const long long mod=1e9+7;
long long dp[200005][3];
int main()
{
int n,l,r;
while(cin>>n>>l>>r)
{
memset(dp,0,sizeof(dp));
dp[0][0]=1,dp[0][1]=0,dp[0][2]=0;
int x,y,z;
x=r/3-(l-1)/3,y=(r+2)/3-(l+1)/3,z=(r+1)/3-l/3;
//余0则是,i-1余0*自己余0+(i-1余1*自己余2)+(i-1余2*自己余1
for(int i=1;i<=n;i++)
{
dp[i][0]=dp[i-1][0]*x%mod+dp[i-1][1]*z%mod+dp[i-1][2]*y%mod;
dp[i][0]%=mod;
dp[i][1]=dp[i-1][0]*y%mod+dp[i-1][1]*x%mod+dp[i-1][2]*z%mod;
dp[i][1]%=mod;
dp[i][2]=dp[i-1][0]*z%mod+dp[i-1][1]*y%mod+dp[i-1][2]*x%mod;
dp[i][2]%=mod;
}
cout<
http://codeforces.com/contest/1105/problem/D
题意:
给n*m的地图,最多9个人,同时有每个人的扩张次数(我开始以为是直线扩张最大长度。。实际是能连续扩张次数。)
地图上有‘#’,‘.’,和数字,数字对应每个人的据点,
从1-n轮流扩张。
地图被扩张完后,输入每个人的据点数目。
垃圾题目 浪费时间 毁我青春。。
注意一点,当矩阵的空间不再减少时候直接结束
#include
using namespace std;
int a[15];
int grp[1005][1005];
struct node
{
node (int xx,int yy)
{
x=xx;
y=yy;
}
int x,y;
};
int n,m,p;
vector node_bfs[15];
vectortem[2];
int s_sum;
int dfs(int depth,int max_depth,int bl,int num)
{
// cout<<"num "<0&&xv<=n&&yv>0&&yv<=m&&!grp[xv][yv])
{
z=1;
s_sum--;
grp[xv][yv]=num;
tem[!bl].push_back(node(xv,yv));
}
}
}
}
}
if(z)
{
return dfs(depth+1,max_depth,!bl,num);
}
else
{
tem[!bl].clear();
return !bl;
}
}
int main()
{
while(cin>>n>>m>>p)
{
s_sum=0;
for(int i=1;i<=p;i++)
{
node_bfs[i].clear();
cin>>a[i];
}
string s;char c;
for(int i=1;i<=n;i++)
{
cin>>s;
for(int j=1;j<=m;j++)
{
c=s[j-1];
//cin>>c;
if(c=='.')
{
grp[i][j]=0;
s_sum++;
}
else if(c!='#')
{
int v=c-'0';
grp[i][j]=v;
node_bfs[v].push_back(node(i,j));
}
else
{
grp[i][j]=-1;
}
}
}
while(s_sum)
{
int qs=s_sum;
// cout<
http://codeforces.com/contest/1100/problem/F
题目大意:有n个汉堡店,每个店里最贵的汉堡是ci元,q次询问,从l到r,所能花费的最多钱数(结束与开始时的金额差),但是花钱不是直接的加减,规则是手里有d元,要花费c元,那支付只后,他还有d^c元。开始是他有非常多个1(rich)。
具体思路:贪心,我们按照右边界的大小进行排序,小的在上面,大的往下安排,然后每一次我们寻找1–> r区间内的线性基,如果当前的线性基能往后移动,我们就选取后面的这个线性基(因为我们对输入的数据进行了排序,后面的r肯定是大的,所以我们将选取的线性基尽量的往后安排肯定是没有问题的,然后我们查询的时候,看一下当前位上有线性基的时候,先判断这个线性基取的时候是从哪个数里面取出来的,然后再看一下这个数是不是大于l的,如果是的话,这个线性基就是可用的,我们通过这些线性基寻找一个最大值就可以了)
最后解题思路就是离线的线性基。
然后 查询l 到r 区间中的最大值是谁 从高位到低位便利
#include
using namespace std;
const int maxn=500005;
int nums[maxn];
struct node
{
int l,r;
int vis;
}tag[maxn];
bool cmp1(node a,node b)
{
if(a.r==b.r) return a.l=0;i--)
{
if (val&(1LL<0;
}
int query_maxs(int l)
{
int ret=0;
for (int i=20;i>=0;i--)
if ((ret^a[i])>ret&&pos[i]>=l)
ret^=a[i];
return ret;
}
int ans[maxn];
int ces[maxn];
int main()
{
int n;
while(cin>>n)
{
for(int i=1;i<=n;i++)
{
// cin>>ces[i];
scanf("%d",&ces[i]);
}
int q;
// cin>>q;
scanf("%d",&q);
for(int i=0;i>tag[i].l>>tag[i].r;
scanf("%d%d",&tag[i].l,&tag[i].r);
tag[i].vis=i;
}
sort(tag,tag+q,cmp1);
int r=1;
for(int i=0;i
http://codeforces.com/contest/1101/problem/F
#include
using namespace std;
typedef long long ll;
const int maxn = 405;
int dp[maxn][maxn]; // dp[i][j][k] 表示从i出发到达j中间停留k次的最长间隔。
int a[maxn];
int pos[maxn];
struct data
{
int f,c,r;
data(){}
data(int ff,int cc,int rr)
{
f=ff;
c=cc;
r=rr;
}
};
vector G[maxn];
int main()
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
for(int i=1;i<=m;i++)
{
int s,f,c,r;
scanf("%d%d%d%d",&s,&f,&c,&r);
G[s].push_back(data(f,c,r));//离线处理每个起点为s的查询
}
ll ans=0;
for(int i=1;i<=n;i++)
{
for(int j=i+1;j<=n;j++)
{
dp[j][0]=a[j]-a[i];
int pos=0;
for(int k=1;k<=n;k++)
{
dp[j][k]=a[j]-a[i];
while(pos+1<=j&&dp[pos+1][k-1]
Educational Codeforces Round 58 (Rated for Div. 2)
http://codeforces.com/contest/1101/problem/G
解题思路 线性基的性质
#include
using namespace std;
int a[200005],p[66];
void Linear(int x)
{
int xe=x;
// cout<=0;i--)
{
if((x&(1<>n)
{
memset(p,0,sizeof(p));
int t=0;
for(int i=0;i>a[i];
if(i==0) t=a[i];
else t^=a[i];
}
if(t==0 )
{
cout<<-1<=0;i--)
{
if(p[i])
{
ans++;
// cout<