暂存
最近因为学校的"多校联测"的题库不翼而飞,导致很多我在上面提交过的代码直接消失了,手上侥幸还存有两道题,以防电脑关机丢失,故暂存于此。
T1
题目大意:
求
\[\sum _{i=l}^{r}(i-1)\sum _{j=1}^{n}⌈ log _{i} j⌉
\]
\[范围:2\leq l,r,n\leq 1e18,注:多组测试数据T\leq 1e5
\]
只贴个代码,式子一推就比较显然了
对了做题题目自带的知识补充不要忘(做题要用):
\[\sum _{i=1}^{n}i ^3 =(\frac{n(n+1)}{2}) ^2
\]
#include<bits/stdc++.h>
using namespace std;
#define int __int128
#define _2 499122177
#define _6 166374059
#define _4 748683265
const int M=1e24;
const int p=998244353;
int m,ans;
vector<int>f[65];
int l,r,n,t,powll[65];
inline int quickpow(int a,int b){
int res=1;
while(b){
if(b&1)res=res*a;
a=a*a;
b>>=1;
}return res;
}
inline int down(int x,int y,int k){
x--;
if(k==1)return (x+1+y)*(y-x)%p*_2%p;
if(k==2)return (y*(y+1)%p*(2*y+1)%p-x*(x+1)%p*(2*x+1)%p+p)*_6%p;
if(k==3)return ((y+1)*y%p*(y+1)%p*y%p-(x+1)*x%p*(x+1)%p*x%p+p)*_4%p;
return (f[k][y]-f[k][x]+p)%p;
}
inline int get(int x){
int l,r,res=0;
for(int i=60;i>=1;i--){
r=powll[i],l=powll[i+1]+1;
if(r>x){
if(l<=x)res=(res+(x+l-2)*(x-l+1)%p*_2%p*n%p*(i+1)%p-down(l,x,i+1)+(x-l+1)+p)%p;
return res;
}
if(l<=r){
res=(res+(r+l-2)*(r-l+1)%p*_2%p*n%p*(i+1)%p-down(l,r,i+1)+(r-l+1)+p)%p;
}
}
return (int)((res+(x+n-1)*(x-n)%p*_2%p*n%p-down(n+1,x,1)+(x-n)+p)%p);
}
inline void iint(){
for(int i=4;i<=61;i++){
f[i].push_back(0);
for(int j=1;j<=1000000;j++){
int k=quickpow(j,i);
if(k>M)break;
f[i].push_back((f[i].back()+k)%p);
}
}
}
inline int read(){
register int ans=0;register char ch=getchar_unlocked();
while(ch<'0' || ch>'9'){ch=getchar_unlocked();}
while(ch>='0' && ch<='9'){ans=(ans<<1)+(ans<<3)+(ch^48);ch=getchar_unlocked();}
return ans;
}
inline void print(int n){
if(n>9)print(n/10);
putchar_unlocked(n%10+48);
}
int poww(int x,int k){
if(k==1)return x;
return pow(x,1.0/k);
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
t=read();
iint();
while(t--){
l=read();r=read();n=read();
int k=log2((long long)n)+1;
for(int i=1;i<=k;i++){
powll[i]=poww(n,i);
}
print((get(r)-get(l-1)+p)%p);
putchar_unlocked('\n');
}
return 0;
}
T2
题目大意:
一棵数,\(n\)个点,每个点都有一个权值\(ai\),\(q\)次询问,问从\(x\)点到\(y\)点经过的路径上是否存在一个点的权值为\(w\)
\[范围:a[i]\leq n,q\leq 5e5
\]
出题人没卡主席树,空间刚好不炸直接碾过去了
#include<bits/stdc++.h>
using namespace std;
const int N=5e5+5;
int n,m,a[N],dep[N],dfn[N],num;
int h[N],tot,root[N],f[N];
int x,y,z,t,k,cnt,st[N][21];
struct sb{
int nxt,to;
}e[N<<1];
struct op{
int l,r,sum;
}tr[16000005];
void add(int x,int y){
e[++cnt]={h[x],y};
h[x]=cnt;
}
inline void pushup(int rt){
tr[rt].sum=tr[tr[rt].l].sum+tr[tr[rt].r].sum;
}
void build(int &rt,int l,int r){
rt=++tot;
if(l==r)return;
int mid=(l+r)>>1;
build(tr[rt].l,l,mid);
build(tr[rt].r,mid+1,r);
}
int insert(int rt,int l,int r,int x){
int root=++tot;
tr[root]=tr[rt];
if(l==r){
tr[root].sum++;
return root;
}
int mid=(l+r)>>1;
if(x<=mid)tr[root].l=insert(tr[root].l,l,mid,x);
else tr[root].r=insert(tr[root].r,mid+1,r,x);
pushup(root);
return root;
}
bool query(int u,int v,int k,int w,int l,int r,int x){
int op=tr[u].sum+tr[v].sum-tr[k].sum-tr[w].sum;
if(op==0)return 0;
if(l==r&&l==x)return 1;
int mid=(l+r)>>1;
if(x<=mid)return query(tr[u].l,tr[v].l,tr[k].l,tr[w].l,l,mid,x);
return query(tr[u].r,tr[v].r,tr[k].r,tr[w].r,mid+1,r,x);
}
void dfs(int x,int fa){
root[x]=insert(root[fa],0,n,a[x]);
dfn[x]=++num;dep[x]=dep[fa]+1;
st[dfn[x]][0]=x;f[x]=fa;
// cout<<st[dfn[x]][0]<<' ';
for(int i=h[x];i;i=e[i].nxt){
int y=e[i].to;
if(y==fa)continue;
dfs(y,x);
}
}
inline int get(int x,int y){
return dep[x]<dep[y]?x:y;
}
inline int lca(int x,int y){
if(x==y)return x;
if((x=dfn[x])>(y=dfn[y]))swap(x,y);
int k=__lg(y-x++);
return f[get(st[x][k],st[y-(1<<k)+1][k])];
}
inline int read(){
register int ans=0;register char ch=getchar_unlocked();
while(ch<'0' || ch>'9'){ch=getchar_unlocked();}
while(ch>='0' && ch<='9'){ans=(ans<<1)+(ans<<3)+(ch^48);ch=getchar_unlocked();}
return ans;
}
inline void print(int n){
if(n>9)print(n/10);
putchar_unlocked(n%10+48);
}
signed main(){
// freopen("in.in","r",stdin);
// freopen("out.out","w",stdout);
n=read();m=read();
for(int i=1;i<=n;i++)a[i]=read();
build(root[0],0,n);
for(int i=1;i<n;i++){
x=read();y=read();
add(x,y);add(y,x);
}
dfs(1,0);
for(int j=1;j<=__lg(n);j++){
for(int i=1;i+(1<<j)-1<=n;i++){
st[i][j]=get(st[i][j-1],st[i+(1<<(j-1))][j-1]);
}
}
while(m--){
x=read();y=read();z=read();
int lc=lca(x,y);
// cout<<x<<' '<<y<<' '<<lc<<endl;
if(!query(root[x],root[y],root[lc],root[f[lc]],0,n,z)){
putchar_unlocked('N');
putchar_unlocked('o');
putchar_unlocked('t');
}
putchar_unlocked('F');
putchar_unlocked('i');
putchar_unlocked('n');
putchar_unlocked('d');
putchar_unlocked('\n');
}
return 0;
}