【題目描述】
【解題思路】
問題轉化為有多少個【l,r】使得a的l~r這個區間乘起來是k的倍數。 k√
的時間分解k的質因數。
列舉l,可以發現r具有單調性,也就是若【l,r】合法,那麼【l,r+1】也合法。
用尺取法就可以解決。
時間複雜度:o(
2n+k
√)
【**】
#include
#include
using
namespace
std;
typedef
long
long ll;
int n,k;
const
int n=1e5;
int d[n+100],kl,sl,ty[n+100],cnt;
ll f[n+100];
ll ans;
int pck(int x,int v)
}return x;
}bool check()
int main()
} sl=-1;
for(int i=1;i<=n;i++) scanf("%d",&d[i]);
int la=0;
for(int i=1;i<=n;i++)
if(check()) ans+=(n-la+1);
yu=pck(d[i],-1);
if(!(yu%kl)) sl--;
}printf("%lld\n",ans);
return
0;}
【題目描述】
【解題思路】
異或有結合律,交換律。
但題目需要求和,加法不能跟異或同時做。
其實把每乙個數字x,分解成∑2
ki,也就是把x轉化為二進位制來做。建立logx個線段樹,分別表示二進位制的第k位的情況(也就是【l,r】這一區間,xi轉化成二進位制,第k位多少個1,l≤i≤r)。
若【l,r】這一區間xor 2^k,則把線段樹k中的【l,r】範圍的1變成0,0變成1。(統計1的個數sum1就行,打反轉標記。反轉的話1的個數就等於r-l+1-sum1)
【**】
#include
#include
using
namespace
std;
typedef
long
long ll;
const
int n=1e5+10;
const
int kp=20;
int n;
int d[n];
struct data
t[21][n<<2];
ll ans;
int gd(int x,int y)
void build(int w,int ro,int l,int r)
int mid=(l+r)>>1;
build(w,ro<<1,l,mid); build(w,ro<<1|1,mid+1,r);
t[w][ro].s=t[w][ro<<1].s+t[w][ro<<1|1].s;
}void down(int w,int ro,int l,int r)
}void updata(int w,int ro,int l,int r,int li,int ri)
int mid=(l+r)>>1;
down(w,ro,l,r);
updata(w,ro<<1,l,mid,li,ri); updata(w,ro<<1|1,mid+1,r,li,ri);
t[w][ro].s=t[w][ro<<1].s+t[w][ro<<1|1].s;
}int query(int w,int ro,int l,int r,int li,int ri)
int main()
else
if(c==2)}}
}
【題目描述】
【解題思路】
首先想到的就是數字dp(lr那麼大,除此之外也沒什麼可以做的了)。
dp的狀態:f[第i位][字串的狀態][當前的麻辣值][是否有前導零][是否達到上界]=方案數
但,如果把所有的字串的狀態直接記下來,是很難轉移的,不可能再重新匹配。
所以想到建ac自動機來維護,字串的狀態也就是在ac自動機上的位置t(先預處理出字串所對應的麻辣值)。列舉下一位的數字x(0~19),直接轉移到t->c[x]的位置,再加上麻辣值,累計方案數。
最後統計所有位置,麻辣值不超過k的方案數的和。
【**】
#include
#include
#include
using namespace std;
const int mods=1000000007;
const int ln=505;
struct data t[ln];
int dl[210],dr[210],q[210];
int root,n,m,k,cnt;
int f[2][205][705][2][2];
void buildfail()
k=t[k].fail;
}if(flag) t[v].fail=t[k].r[i]; else t[v].fail=root;
(t[v].s+=t[t[v].fail].s)%=mods;
q[++tail]=v;
} else t[fnow].r[i]=t[t[fnow].fail].r[i];
}}int getans(int a)}}
int res=0;
for(int i=0;i<=cnt;i++)
for(int h=0;h<=k;h++)
for(int p1=0;p1<2;p1++)
for(int p2=0;p2<2;p2++)
(res+=f[(a[0]&1)][i][h][p1][p2])%=mods;
return res;
}int main()
now=t[now].r[cd];
}scanf("%d",&cd);
(t[now].s+=cd)%=mods;
}buildfail();
printf("%d\n",((getans(dr)-getans(dl))%mods+mods)%mods);
return
0;}
NOIP2017提高組模擬賽4 (總結)
這道題就是很簡單的bfs,可以觀察到n變化到m是近似成倍增長的。其實從最小到最大的變化也就只有30次而已。include include include typedef long long ll using namespace std const int maxl 100 const int oo ...
NOIP2017提高組模擬賽5 (總結)
其實就是將乙個點f拆成向左l向右r的兩個點,然後將所有點排序 不用排序也行,直接找 選第乙個l,從後往前選第乙個不與l同乙個f的r。選最後乙個r,從前往後選第乙個不與r同乙個f的l。答案中的最大值即為兩點之間的最遠距離。證明如下 0 數學方法 把01看成a b個點。設s a b,x 最少要翻轉次數,...
NOIP2017提高組 模擬賽 26(總結)
題目描述 解題思路 構造法 假設現在有m個點,刪除乙個點,剩下的m 1個點都已經確定,那麼刪除的這個點應該染什麼顏色。假如這個點所在的行的點數為奇數,那麼點的染色只與它所在的列有關 若列有偶數個點,那麼這個點的顏色就可以確定了,哪種顏色少選哪種。否則隨便選 假如這個點所在的列的點數為奇數,與上面類似...