A题。

发现是递推可以解决这道题,a[n]=6*a[n-1]-a[n-2]。因为是求和,可以通过一个三维矩阵加速整个计算过程,主要是预处理出2^k时的矩阵,可以通过这道题

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define LL long long
using namespace std; const int MOD=1e9+; int quick(int a,int b){
int res=;
while(b){
if(b&){
res+=a;
if(res>=MOD) res-=MOD;
}
b>>=;
a+=a;
if(a>=MOD) a-=MOD;
// cout<<"YES"<<endl;
}
return res;
} struct Matrix{
int a[][];
void init(){
for(int i=;i<;i++)
for(int j=;j<;j++) a[i][j]=;
}
/* Matrix operator= (Matrix p){
for(int i=0;i<3;i++){
for(int j=0;j<3;j++) a[i][j]=p.a[i][j];
}
return *this;
}*/
Matrix operator* (Matrix s){
Matrix res;
for(int i=;i<;i++)
for(int j=;j<;j++){
res.a[i][j]=;
for(int k=;k<;k++){
res.a[i][j]+=(long long)a[i][k]*s.a[k][j]%MOD;
if(res.a[i][j]>=MOD) res.a[i][j]-=MOD;
/// cout<<"YES"<<endl;
}
}
return res;
}
}a,power[]; void init(){
power[].a[][]=,power[].a[][]=,power[].a[][]=;
power[].a[][]=,power[].a[][]=,power[].a[][]=;
power[].a[][]=,power[].a[][]=MOD-,power[].a[][]=; a.a[][]=,a.a[][]=,a.a[][]=;
a.a[][]=,a.a[][]=,a.a[][]=;
a.a[][]=,a.a[][]=,a.a[][]=; for(LL i=;i<;i++){
power[i]=power[i-]*power[i-];
}
/* for(int i=0;i<3;i++){
for(int j=0;j<3;j++)
cout<<power[0].a[i][j]<<" ";
cout<<endl;
}*/
} int main(){
init();
int T;LL n;
scanf("%d",&T);
while(T--){
scanf("%I64d",&n); /////不能用lld
Matrix ans=a;
int cnt=;
while(n){
if(n&) ans=ans*power[cnt];
n>>=;
cnt++;
}
printf("%d\n",ans.a[][]);
} return ;
}

B题。留坑

C题。这道题其实和G题一样,DP可以解决。记录前两个位置的状态,限制第三个位置的状态,进行转移即可。因为是一个环,所以,在选择最后两个位置的状态时要和最开始的两个位置相容,进行枚举即可。所以要计算四种开始的状态,分别是(00),(01)(10)(11)。

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm> using namespace std; int dp[][][][][][];//////fisrt ,second
const int MOD=1e9+; int add(int a,int b){
a+=b;
if(a>MOD) a-=MOD;
return a;
} int main(){
int T,n,p;
scanf("%d",&T);
memset(dp,,sizeof(dp));
dp[][][][][][]=dp[][][][][][]=dp[][][][][][]=dp[][][][][][]=;
for(int fst=;fst<;fst++){
for(int sec=;sec<;sec++){
for(int i=;i<=;i++){
for(int k=;k<=min(i,);k++){
///select
if(k){
dp[fst][sec][i][k][][]=add(dp[fst][sec][i][k][][],dp[fst][sec][i-][k-][][]);
dp[fst][sec][i][k][][]=add(dp[fst][sec][i][k][][],dp[fst][sec][i-][k-][][]);
}
///un select
dp[fst][sec][i][k][][]=add(dp[fst][sec][i][k][][],add(dp[fst][sec][i-][k][][],dp[fst][sec][i-][k][][]));
dp[fst][sec][i][k][][]=add(dp[fst][sec][i][k][][],add(dp[fst][sec][i-][k][][],dp[fst][sec][i-][k][][]));
}
}
}
}
while(T--){
scanf("%d%d",&n,&p);
int ans=;
for(int fst=;fst<;fst++){
for(int sec=;sec<;sec++){
for(int i=;i<;i++){
for(int j=;j<;j++){
if(!(fst&i)&&!(sec&j)){
ans=add(ans,dp[fst][sec][n][p][i][j]);
ans=add(ans,dp[fst][sec][n][p][i][j]);
}
}
}
}
}
printf("%d\n",ans);
}
return ;
}

D题。这道题是学习窝bin的。线段树可以解决。

首先,要知道的是gcd(a1,a2)=gcd(a1,a1-a2)。则gcd(x-a1,x-a2)=gcd(x-a1,a1-a2)。

那么,对于gcd(x-a1,x-a2,x-a3.....x-an)=gcd(x-a1,a1-a2,a2-a3.....a[n-1]-a[n])。使用线段树来维护a1-a2,a2-a3....这个差分序列,同时记录x的值以及头尾两个a1,an的值。使用线段树更新,即可。具体可看代码.

 #include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
const int MAXN = ;
long long gcd(long long a,long long b){
if(b == )return a;
return gcd(b,a%b);
}
struct Node {
int l,r;
int a,b;
int first,last;
int g;
int val;
}segTree[MAXN<<];
void push_up(int i) {
segTree[i].first = segTree[i<<].first;
segTree[i].last = segTree[(i<<)|].last;
segTree[i].val = gcd(segTree[i<<].val,segTree[(i<<)|].val);
segTree[i].val = gcd(segTree[i].val,abs(segTree[i<<].last-segTree[(i<<)|].first));
segTree[i].g = gcd(segTree[i].val,segTree[i].first);
}
void Update_node(int i,int a,int b) {
segTree[i].first = a*segTree[i].first+b;
segTree[i].last = a*segTree[i].last+b;
segTree[i].g = gcd(segTree[i].first,segTree[i].val);
segTree[i].a *= a;
segTree[i].b = a*segTree[i].b+b;
}
void push_down(int i) {
if(segTree[i].l == segTree[i].r)return;
int a = segTree[i].a;
int b = segTree[i].b;
if(a != || b != ) {
Update_node(i<<,a,b);
Update_node((i<<)|,a,b);
a = ;
b = ;
}
}
int a[MAXN];
void build(int i,int l,int r) {
segTree[i].l = l;
segTree[i].r = r;
segTree[i].a = ;
segTree[i].b = ;
if(l == r) {
segTree[i].first = a[l];
segTree[i].last = a[l];
segTree[i].val = ;
segTree[i].g = a[l];
return;
}
int mid = (l+r)/;
build(i<<,l,mid);
build((i<<)|,mid+,r);
push_up(i);
}
void update(int i,int l,int r,int a,int b) {
if(segTree[i].l == l && segTree[i].r == r) {
Update_node(i,a,b);
return;
}
push_down(i);
int mid = (segTree[i].l+segTree[i].r)/;
if(r <= mid)update(i<<,l,r,a,b);
else if(l > mid)update((i<<)|,l,r,a,b);
else {
update(i<<,l,mid,a,b);
update((i<<)|,mid+,r,a,b);
}
push_up(i);
}
int query(int i,int l,int r) {
if(segTree[i].l == l && segTree[i].r == r)
return segTree[i].g;
push_down(i);
int mid = (segTree[i].l+segTree[i].r)/;
if(r <= mid)return query(i<<,l,r);
else if (l > mid)return query((i<<)|,l,r);
else return gcd(query(i<<,l,mid),query((i<<)|,mid+,r));
} int main(){
int n,m;
while(scanf("%d%d",&n,&m) == ) {
for(int i = ;i <= n;i++)scanf("%d",&a[i]);
build(,,n);
int op;
int l,r,x;
while(m--) {
scanf("%d",&op);
if(op == ) {
scanf("%d%d%d",&l,&r,&x);
update(,l,r,-,x);
} else {
scanf("%d%d",&l,&r);
printf("%d\n",query(,l,r));
}
}
}
return ;
}

E题推理。这里注意必须从说+号的人下手。由于有m个人说真话,假设说了+A的人都说了真话,那么-A的人就是假话,而说其他的+的人也说了假话,说其他-的人说了真话。这里统计说了真话的人,如果>m,则说了+A的人都说了假话。如果刚好,我们统计这种“刚好”有多少种,置为待定状态,把iscrime[A]=true。则对于说了A是罪犯的人,因无法判断A是否真的是罪犯,输出未定。如果iscrime[A]=false,对于说了A是罪犯的,则肯定是说了假话。对于A不是罪犯的,如果这时A是true,因为A未定,所以输出待定,否则,如果A是false,则肯定是说了真话,因为对于iscrime[A]=false的条件,只有当说真话的人肯定说了假话,亦即是说了+A的人肯定说了假话,才会是false。

由于题目条件是肯定有解,所以如果“刚好”的情况只有一种,则谁说真谁说假是可以确定的。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm> using namespace std; const int MAX=1e5+; int say[MAX],vote[MAX],nvote[MAX],pcnt,ncnt;
bool iscrime[MAX]; int main(){
int T,n,m;
scanf("%d",&T);
while(T--){
pcnt=ncnt=;
scanf("%d%d",&n,&m);
memset(vote,,sizeof(vote));
memset(nvote,,sizeof(nvote));
for(int i=;i<=n;i++){
scanf("%d",&say[i]);
if(say[i]>) vote[say[i]]++;
else nvote[-say[i]]++;
if(say[i]>) pcnt++;
else ncnt++;
}
memset(iscrime,false,sizeof(iscrime));
int counts=;
for(int i=;i<=n;i++){
if(vote[i]+ncnt-nvote[i]==m){
iscrime[i]=true;
counts++;
}
}
if(counts==){
int find;
for(int i=;i<=n;i++){
if(say[i]>)
if(iscrime[say[i]]){
puts("Truth");
}
else puts("Lie");
else{
if(iscrime[-say[i]]){
puts("Lie");
}
else puts("Truth");
}
}
}
else{
for(int i=;i<=n;i++){
if(say[i]>){
if(iscrime[say[i]]){
puts("Not defined");
}
else puts("Lie");
}
else{
if(iscrime[-say[i]]){
puts("Not defined");
}
else puts("Truth");
}
}
} }
return ;
}

F题使用set就可以解决了。

G题,DP题。和C题是一样的。先枚举DP假如是一条直线时,连续的个数<=6个时的所有情况。再按这种方式枚举,减去因为首尾相连可能出现>=7的情况,就可以得到结果.

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; const int MAX=;
const int MOD=;
int dp[MAX][][]; int main(){
int n,T,icase=;
scanf("%d",&T);
while(T--){
scanf("%d",&n);
printf("Case #%d: ",++icase);
if(n<){
int ans=;
for(int i=;i<=n;i++)
ans*=;
// if(n==7) ans-=2;
printf("%d\n",ans%MOD);
continue;
}
memset(dp,,sizeof(dp));
dp[][][]=; dp[][][]=;
for(int i=;i<=n;i++){
for(int j=;j<=;j++)
for(int k=;k<=;k++){
if(k==){
///dp[i][j][k]=0;
for(int p=;p<=;p++)
dp[i][j][k]+=dp[i-][j^][p];
dp[i][j][k]%=MOD;
}
else{
//dp[i][j][k]=0;
dp[i][j][k]+=dp[i-][j][k-];
dp[i][j][k]%=MOD;
}
}
}
int ans=;
for(int j=;j<=;j++){
for(int k=;k<=;k++){
ans+=dp[n][j][k];
}
ans%=MOD;
}
// cout<<ans<<endl;
memset(dp,,sizeof(dp));
for(int e=;e<=;e++){
dp[e+][][]=;
for(int i=e+;i<=n;i++){
for(int j=;j<=;j++)
for(int k=;k<=;k++){
if(k==){
// dp[i][j][k]=0;
for(int p=;p<=;p++)
dp[i][j][k]+=dp[i-][j^][p];
dp[i][j][k]%=MOD;
}
else{
// dp[i][j][k]=0;
// for(int p=1;p<k;p++)
dp[i][j][k]+=dp[i-][j][k-];
dp[i][j][k]%=MOD;
}
}
}
for(int p=-e;p<=;p++)
ans-=(dp[n][][p])*;
ans%=MOD;
memset(dp,,sizeof(dp));
}
printf("%d\n",(ans%MOD+MOD)%MOD);
}
return ;
}

FOJ 10月赛题 FOJ2198~2204的更多相关文章

  1. EOJ2018.10 月赛

    EOJ2018.10 月赛 题目一览表(Green color indicate understand and Accept) 来源 考察知识点 完成时间 A oxx 的小姐姐们 EOJ 数学+思维 ...

  2. python+java蓝桥杯ACM日常算法题训练(一)10基础题

    目录 1.简单的a+b 2.第一个HelloWorld程序! 3.三个数最大值 4.密码破译 5.母牛的故事 6.7.8.9.10 @(这里写自定义目录标题) 算法题训练网站:http://www.d ...

  3. FOJ有奖月赛-2016年8月(daxia专场之过四题方有奖)

    http://acm.fzu.edu.cn/contest/list.php?cid=152 主要是a题, lucas定理, 就这一版能过..  记录一下代码, 另外两个最短路  一个模拟,没什么记录 ...

  4. EOJ2018.10 月赛(B 数学+思维题)

    传送门:Problem B https://www.cnblogs.com/violet-acmer/p/9739115.html 题意: 找到最小的包含子序列a的序列s,并且序列s是 p -莫干山序 ...

  5. EOJ2018.10 月赛(A 数学+思维题)

    传送门:Problem A https://www.cnblogs.com/violet-acmer/p/9739115.html 题意: 能否通过横着排或竖着排将 1x p 的小姐姐填满 n x m ...

  6. AtCoder Grand Contest 1~10 做题小记

    原文链接https://www.cnblogs.com/zhouzhendong/p/AtCoder-Grand-Contest-from-1-to-10.html 考虑到博客内容较多,编辑不方便的情 ...

  7. HDU 4704 Sum (2013多校10,1009题)

    Sum Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submi ...

  8. HDU 4699 Editor (2013多校10,1004题)

    Editor Time Limit: 3000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Su ...

  9. HDU 4705 Y (2013多校10,1010题,简单树形DP)

    Y Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submiss ...

随机推荐

  1. Eclipse中Axis2发布WebService

    介绍:Axis是apache下一个开源的webservice开发组件. l  开发工具下载: 1.  eclipse的Java EE版本.下载地址:http://www.eclipse.org/dow ...

  2. IIS Express配置多站点同时运行

    环境:Win10 Pro.Visual Studio 2015 Community.IIS Express 10 VS2015集成IIS Express,所以无需单独下载, 默认安装位置:C:\Pro ...

  3. Java系列学习(十一)-内部类

    1.内部类 (1)把类定义在另一个类的内部,该类就称为内部类 (2)内部类的访问规则 A:内部类可以直接访问外部类的成员,包括私有 B:外部类要想访问内部类的成员,必须创建对象 (3)内部类的分类 A ...

  4. PHP常用的一些函数:

    背景:这一次是对一些函数进行整理,方便以后的使用. 1.date(); date()函数的作用是获取当前日期时间,由于PHP 5.0对date()函数进行了重写,因此,当前的日期时间函数比系统时间少了 ...

  5. BAT文件如何注释

    1.BAT文件中如何注释: 1.:: 注释内容(第一个冒号后也可以跟任何一个非字母数字的字符) 2.rem 注释内容(不能出现重定向符号和管道符号) 3.echo 注释内容(不能出现重定向符号和管道符 ...

  6. 移动web——媒体查询

    基本概念 响应式开发在没有媒体查询前,也可以通过js来实现,但是人们基本不会考虑,特别繁琐.在出现了媒体查询,才开始逐渐推广响应式.实际开发中,在时间与金钱充足的情况下还是别做响应式,影响性能,维护麻 ...

  7. c指针之内存释放

    // 1.正常使用包含指针的结构体 // 2.正常使用元素类型为指针的vector #include<string.h> #include<stdio.h> #include& ...

  8. 离线安装Selenium

    https://blog.csdn.net/poem_ruru/article/details/79032140

  9. CSS固定布局:960GS

    960栅格系统 <!DOCTYPE html> <html lang="en"> <head> <meta charset="U ...

  10. Gpupdate命令详解

    刷新本地和基于 Active Directory 的组策略设置,包括安全设置.该命令可以取代 secedit 命令中已经过时的 /refreshpolicy 选项. MS-DOS命令语法 gpupda ...