利用webAssembly技術讓提升瀏覽器解壓效能
阿新 • • 發佈:2020-08-12
單調佇列
#include<bits/stdc++.h> using namespace std; deque<int> q; int a[10000000]; int main(){ int n,k; cin >>n >>k; for(int i=1;i<=n;i++) { cin >>a[i]; } for(int i=1;i<=n;i++) { while(!q.empty()&&q.front()<=i-k)q.pop_front(); while(!q.empty()&&a[i]<a[q.back()])q.pop_back(); q.push_back(i); if(i-k>=0)cout << a[q.front()] << " "; } cout <<endl; while(!q.empty())q.pop_front(); for(int i=1;i<=n;i++) { while(!q.empty()&&q.front()<=i-k)q.pop_front(); while(!q.empty()&&a[i]>a[q.back()])q.pop_back(); q.push_back(i); if(i-k>=0)cout << a[q.front()] << " "; } }
快速冪
記得隨時取模。
#include<bits/stdc++.h> using namespace std; long long b,p,k; long long apow(int a,int b) { long long ans=1; while(b) { if(b&1) { ans=((ans%k)*(a%k))%k; } a=((a%k)*(a%k))%k; b=b>>1; } return ans%k; } int main(){ cin >> b >> p >> k; cout << b<<"^"<<p<<" mod "<< k<< "="<< apow(b,p)%k; }
並查集
記得初始化f陣列啊( )
#include<bits/stdc++.h> using namespace std; int n,m,p; int f[200086]; int find(int x) { if(f[x]==x)return x; return f[x]=find(f[x]);//路徑壓縮 } void hb(int x,int y) { int fx=find(x); int fy=find(y); if(fx!=fy) f[fx]=fy; return ; } void solve(){ cin >> n >> m ; for(int i=1;i<=n;i++) { f[i]=i; } while(m--) { int z,x,y; cin >> z >> x >> y; if(z==1) hb(x,y); else { if(find(x)==find(y)) { cout << "Y" << endl; } else { cout << "N" << endl; } } } return; } int main() { solve(); return 0; }
樹狀陣列
維護一些有字首性質的東西
#include<iostream>
using namespace std;
int tr[10000000];
int n,m;
int lowbit(int x)//返回最低位的1
{
return x&(-x);
}
void plu(int pl,int val)
{
for(;pl<=n;pl+=lowbit(pl))//+lowbit到一個包含於它的更大區間
{
tr[pl]+=val;
}
return;
}
void inputDa()
{
cin >> n >> m;
for(int i=1;i<=n;i++)
{
int j;
cin >> j;
plu(i,j);
}
}
int su(int x,int y)
{
int su=0;
for(;y;y-=lowbit(y))//-lowbit到一個不包含它的極大區間
{
su+=tr[y];
}
for(;x;x-=lowbit(x))
{
su-=tr[x];
}
return su;
}
void solve(){
for(int i=1;i<=m;i++)
{
int j;
cin >> j;
if(j==1)
{
int x,k;
cin >> x >> k;
plu(x,k);
}
else
{
int x,y;
cin >> x >> y;
cout << su(x-1,y) << endl;
}
}
}
int main()
{
inputDa();
solve();
return 0;
}
Kruskal
最小生成樹的比較快的演算法(應該比加了堆優化的prim快吧)
#include<bits/stdc++.h>
using namespace std;
int n,m,ans;
int f[50086];
struct edge{
int u,v,val;
};
edge e[2000086];
bool cmp(edge x,edge y)
{
return x.val < y.val;
}
int find(int x)
{
if(f[x]==x)return x;
return f[x]=find(f[x]);
}
void hb(int x,int y)
{
int fx=find(x);
int fy=find(y);
if(fx!=fy)
f[fx]=fy;
return ;
}
void inputData()
{
cin >> n >> m ;
//如果m<n-1必然不連通
if(m<n-1)
{
cout << "orz";
return;
}
//並查集初始化
for(int i=1;i<=n;i++)
{
f[i]=i;
}
for(int i=1;i<=m;i++)
{
int x,y,v;
cin >> x >> y >> v;
e[i].u=x;
e[i].v=y;
e[i].val=v;
}
}
void solve(){
sort(e+1,e+m+1,cmp);
int num=1,i=0;//num記錄當前的邊,i記錄有效合併
while(i<n-1)//當i=n-1的時候合併完成
{
if(num>m)//如果所有的邊都用了還不能完成合並,說明圖不連通
{
cout << "orz";
return;
}
int u,v,dis;
u=e[num].u;
v=e[num].v;
dis=e[num].val;
num++;
if(find(u)==find(v))//如果連通就繼續迴圈
{
continue;
}
else//否則合併並記錄答案
{
hb(u,v);
i++;
ans+=dis;
}
}
cout << ans;
return;
}
int main()
{
inputData();
solve();
return 0;
}
dij
跑純最短路時比較快的演算法
不能處理負環(SPFA,請)
懶惰刪除聽說加不加無所謂,最好加上吧
#include<bits/stdc++.h>
using namespace std;
typedef struct{int v,w;} abc;//v編號,w存ans
struct node{
int to,nxt,val;
};
node e[600100],d[600100];
int num,n,m,a,s,ans[200100];
abc x;
bool vis[200100];
priority_queue <abc> q;//存值
bool operator<(const abc&a,const abc &b) {return a.w>b.w;}
void ins(int u,int v,int val)//插入操作
{
num++;
e[num].to=v;
e[num].val=val;
e[num].nxt=d[u].nxt;
d[u].nxt=num;
return ;
}
void inputDa()
{
cin >> n >> m >> s;//n個點,m條邊
for(int i=1;i<=m;i++)
{
int u,v,val;
cin >> u >> v >> val;
ins(u,v,val);
}
}
void find()//找出距離原點最近的
{
if(!q.empty())
{
x=q.top();
q.pop();
}
return;
}
void clr()
{
for(int i=1;i<=n;i++)
{
ans[i]=(1<<31)-1;
}
}
void dij()
{
x.v=s;
x.w=0;
q.push(x);
ans[s]=0;
while(!q.empty())//一共n個點,每個點都被找出一次
{
find();//找離原點最近的點
if(vis[x.v])continue;//懶惰刪除
vis[x.v]=1;
//cout << x.v << " " << x.w << endl;
for(int i=d[x.v].nxt;i;i=e[i].nxt)
{
ans[e[i].to]=min(ans[e[i].to],ans[x.v]+e[i].val);//遍歷並更新
if(vis[e[i].to]==0)
{
abc tmp;
tmp.v=e[i].to;
tmp.w=ans[e[i].to];
q.push(tmp);
}
}
}
return;
}
void outputAns(){
for(int i=1;i<=n;i++)
{
cout << ans[i] << " ";
}
}
int main()
{
inputDa();
clr();
dij();
outputAns();
return 0;
}