I题 签到 注意只有0的时候答案为1
#include <bits/stdc++.h>
using namespace std;
#define FORP(i,a,b) for(int i=a;i<=b;i++)
void solve(){
int n;
char ch;
cin>>n>>ch;
string s;cin>>s;
s='#'+s;
FORP(i,1,n){
int data=abs(s[i]-ch);
if(data==0){
continue;
}
else{
if(data<10){
printf("%d\n",(n-i)*2+1);
return;
}
else{
printf("%d\n",(n-i)*2+2);
return ;
}
}
}
printf("1\n");
}
int main(){
int T;
cin>>T;
while(T--){
solve();
}
return 0;
}
顺着思路模拟一遍,每次都是在之前那个map上更新答案
用两个map就可以了
#include <bits/stdc++.h>
using namespace std;
#define FORP(i,a,b) for(int i=a;i<=b;++i)
typedef pair<int,int> Pair;
#define mp(a,b) make_pair(a,b)
map<Pair,int>mymap[3];
void solve(){
int n;cin>>n;
int ans=0;
mymap[0].clear();
mymap[1].clear();
FORP(i,1,n){
int k;cin>>k;
FORP(j,1,k){
int x,y;
cin>>x>>y;
int temp=mymap[i%2][mp(x,y)]=mymap[!(i%2)][mp(x,y)]+1;
ans=max(ans,temp);
}
mymap[!(i%2)].clear();
}
cout<<ans<<endl;
}
int main(){
int T;cin>>T;
while(T--){
solve();
}
return 0;
}
H.
先正着思考 好像不太好更新
根据正难则反的原则
倒着推一遍
单独考虑x和y的长度
It’s guaranteed that a wave will not cover the other completely.
你会发现答案的更新
ans+=(nowx-小于他的最大值)
这里有点小trick 可以lower_bound找到大于等于nowx的第一个位置,然后往前移动1次,即迭代器–
#include <bits/stdc++.h>
using namespace std;
#define FORP(i,a,b) for(int i=a;i<=b;++i)
#define REP(i,a,b) for(int i=a;i>=b;--i)
typedef pair<int,int> Pair;
#define ll long long
#define mp(a,b) make_pair(a,b)
struct node{
ll x,y;
}p[100100];
set<ll> s;
int main(){
int n;
while(cin>>n){
FORP(i,1,n){
cin>>p[i].x>>p[i].y;
}
ll ans=0;
s.clear();
s.insert(0);
REP(i,n,1){
set<ll>::iterator It=s.lower_bound(p[i].y);
It--;
ans+=p[i].y-(*It);
s.insert(p[i].y);
}
s.clear();
s.insert(0);
REP(i,n,1){
set<ll>::iterator It=s.lower_bound(p[i].x);
It--;
ans+=p[i].x-(*It);
s.insert(p[i].x);
}
cout<<ans<<endl;
}
return 0;
}
Ryuji doesn’t want to study
线段树or树状数组维护一下区间皆可
#include <bits/stdc++.h>
using namespace std;
#define FORP(i,a,b) for(int i=a;i<=b;++i)
#define lowbit(i) (i&(-i))
#define ll long long
ll n,q;
ll a[102000];
ll tree1[102000];
ll tree2[102000];
ll getsum(ll *array,ll x){
ll sum=0;
for(ll i=x;i;i-=lowbit(i)){
sum+=array[i];
}
return sum;
}
void update(ll *array,ll x,ll val){
for(ll i=x;i<=n;i+=lowbit(i)){
array[i]+=val;
}
}
int main(){
while(cin>>n>>q){
FORP(i,1,n){
cin>>a[i];
update(tree1,i,a[i]);
update(tree2,i,a[i]*(n-i+1));
}
FORP(i,1,q){
int aa,l,r;
cin>>aa>>l>>r;
if(aa==1){
printf("%lld\n",getsum(tree2,r)-getsum(tree2,l-1)-(n-r)*(getsum(tree1,r)-getsum(tree1,l-1)));
}
else{
update(tree1,l,r-a[l]);
update(tree2,l,(n-l+1)*(r-a[l]));
a[l]=r;
}
}
}
return 0;
}
K Morgana Net
题目有点长没啥人做
仔细读就发现是个矩阵乘法,然后t很大不得不快速幂搞一下 t这么大=快速幂 这个思想要有
然后想转移???
发现那个函数暗示着什么
根据那个函数写转移就好了。。。
坑点:常数比较恶心 队友带我卡了一下常数
见Mul函数。。
特性:01矩阵 0比较多的时候
#include <bits/stdc++.h>
using namespace std;
#define FORP(i,a,b) for(int i=a;i<=b;++i)
#define REP(i,a,b) for(int i=a;i>=b;--i)
typedef pair<int,int> Pair;
#define ll long long
#define mp(a,b) make_pair(a,b)
struct Matrix
{
ll m[65][65];
ll x,y;
}a,b,e,ans,tran;
int N,M,t;
int nf;
bool zero(ll p,ll q){
return p<=0||q<=0||p>N||q>N;
}
Matrix Mul(Matrix A,Matrix B){
Matrix ans;
memset(ans.m,0,sizeof(ans.m));
ans.x=A.x;
ans.y=B.y;
FORP(i,1,A.x){
FORP(k,1,A.y){
if(!A.m[i][k])continue;
FORP(j,1,B.y){
ans.m[i][j]=ans.m[i][j]^(A.m[i][k]&B.m[k][j]);
}
}
}
return ans;
}
Matrix Matrix_ppow(Matrix A,ll n){
Matrix ret=e;
while(n){
if(n&1) ret=Mul(ret,A);
A=Mul(A,A);
n>>=1;
}
return ret;
}
int calnzero(){
int cnt=0;
FORP(i,1,nf){
if(ans.m[1][i]==1) cnt++;
}
return cnt;
}
int getpos(int n,int i,int j){
return (i-1)*n+j;
}
void init(){
e.x=e.y=nf;
FORP(i,1,nf){//初始化单位矩阵
e.m[i][i]=1;
}
}
int main(){
int T;
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>T;
while(T--){
cin>>N>>M>>t;
nf=N*N;
init();
int m=M>>1;
//根据同余定理 可以先处理成0 1 矩阵
ans.x=1;
ans.y=nf;
FORP(i,1,N){
FORP(j,1,N){
int data;cin>>data;
ans.m[1][getpos(N,i,j)]=data&1;//%2->&1
}
}
b.x=b.y=M;
FORP(i,1,M){
FORP(j,1,M){
int data;cin>>data;
b.m[i][j]=data&1;
}
}
memset(tran.m,0,sizeof(tran.m));
tran.x=tran.y=nf;
//转移矩阵
FORP(i,1,N){
FORP(j,1,N){
FORP(p,i-m,i+m){
FORP(q,j-m,j+m){
if(zero(p,q)) continue;
tran.m[getpos(N,p,q)][getpos(N,i,j)]=b.m[p-i+m+1][q-j+m+1]&1;
}
}
}
}
Matrix temp=Matrix_ppow(tran,t);
ans=Mul(ans,temp);
cout<<calnzero()<<endl;
}
return 0;
}
J题 最大生成树+倍增找LCA
解法1
#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define mp(a,b) make_pair(a,b)
#define FORP(i,a,b) for(int i=a;i<=b;++i)
#define mp(a,b) make_pair(a,b)
#define db(a) (cout<<"->"<<a<<endl)
#define ll long long
const int MAXN = 252005;
typedef pair<ll, ll> Pair;
vector<Pair> G[MAXN];
vector<ll> R[MAXN];
vector<node> E;
ll dist[MAXN],fa[MAXN];
ll p[MAXN][20];
ll lg[MAXN];
ll n,m;
struct node
{
ll from,to;
ll w;
node(ll _from,ll _to,ll _w):from(_from),to(_to),w(_w){}
friend bool operator<(node a,node b){
return a.w>b.w;
}
};
inline void add(ll x,ll y,ll t){
G[x].pb(mp(y,t));
E.pb(node(x,y,t));
}
ll getPos(ll i,ll j){
return (i-1)*m+j;
}
void init(){
FORP(i,0,n*m){
fa[i]=i;
}
memset(dist,0,sizeof(dist));
E.clear();
FORP(i,1,n*m){
G[i].clear();
R[i].clear();
}
}
ll find(ll x){
return x==fa[x]?x:fa[x]=find(fa[x]);
}
ll kruskal(){
ll len=n*m-1;
ll sum=0;
FORP(i,0,(ll)E.size()-1){
ll u=E[i].from;
ll v=E[i].to;
ll cost=E[i].w;
ll fx=find(u);
ll fy=find(v);
if(fx!=fy){
fa[fy]=fx;
sum+=cost;
R[u].pb(v);
R[v].pb(u);
if(--len==0) return 0;
}
}
return 0;
}
int dep[MAXN];
void init_lca(){
for(int i=1;i<=MAXN;i++){
lg[i]=lg[i-1]+(1<<lg[i-1]==i);
}
}
void dfs(int node,int fath){
dep[node]=dep[fath]+1;
p[node][0]=fath;
for(int i=1;(1<<i)<=dep[node];i++){
p[node][i]=p[p[node][i-1]][i-1];
}
for(int i=0;i<R[node].size();++i){
int to=R[node][i];
if(to!=fath)dfs(to,node);
}
}
ll lca(ll x,ll y){
if(dep[x]<dep[y]) swap(x,y);
while(dep[x]>dep[y]){
x=p[x][lg[dep[x]-dep[y]]-1];
}
if(x==y) return x;
for(ll k=lg[dep[x]];k>=0;k--){
if(p[x][k]!=p[y][k]){
x=p[x][k];
y=p[y][k];
}
}
return p[x][0];
}
ll caldist(ll x,ll y){
return dep[x]+dep[y]-2*dep[lca(x,y)];
}
int main(){
while(~scanf("%lld%lld",&n,&m)) {
init();
FORP(i,1,n){
FORP(j,1,m){
char s,t;
ll a,b;
cin>>s>>a>>t>>b;
ll u=getPos(i,j),v;
//其实知道边的建立过程可以不用管字母是啥
if(i<n){
v=getPos(i+1,j);
add(u,v,a);
}
if(j<m){
v=u+1;
add(u,v,b);
}
}
}
sort(E.begin(),E.end());
kruskal();//最大生成树构建
dfs(1,0);//预处理
init_lca();
ll q;
cin>>q;
FORP(i,1,q){
ll x1,y1,x2,y2;
cin>>x1>>y1>>x2>>y2;
ll u=getPos(x1,y1);
ll v=getPos(x2,y2);
printf("%lld\n",caldist(u,v));
}
}
return 0;
}
J题
最大生成树+LCA tarjan版 ->离线
#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define mp(a,b) make_pair(a,b)
#define FORP(i,a,b) for(int i=a;i<=b;++i)
#define mp(a,b) make_pair(a,b)
#define db(a) (cout<<"->"<<a<<endl)
#define ll long long
const int MAXN = 302005;
typedef pair<ll, ll> Pair;
vector<Pair> G[MAXN],que[MAXN];
vector<ll> R[MAXN];
ll dist[MAXN],fa[MAXN],ans[MAXN],vis[MAXN];
ll f[MAXN];
ll n,m;
struct node
{
ll from,to;
ll w;
node(ll _from,ll _to,ll _w):from(_from),to(_to),w(_w){}
friend bool operator<(node a,node b){
return a.w>b.w;
}
};
vector<node> E;
inline void add(ll x,ll y,ll t){
G[x].pb(mp(y,t));
E.pb(node(x,y,t));
}
ll getPos(ll i,ll j){
return (i-1)*m+j;
}
void init(){
FORP(i,0,n*m){
fa[i]=i;
f[i]=i;
}
memset(dist,0,sizeof(dist));
memset(ans,0,sizeof(ans));
memset(vis,0,sizeof(vis));
E.clear();
FORP(i,1,n*m){
G[i].clear();
R[i].clear();
que[i].clear();
}
}
ll find(ll x){
return x==fa[x]?x:fa[x]=find(fa[x]);
}
ll kruskal(){
ll len=n*m-1;
ll sum=0;
FORP(i,0,(ll)E.size()-1){
ll u=E[i].from;
ll v=E[i].to;
ll cost=E[i].w;
ll fx=find(u);
ll fy=find(v);
if(fx!=fy){
fa[fy]=fx;
sum+=cost;
R[u].pb(v);
R[v].pb(u);
if(--len==0) return 0;
}
}
return 0;
}
ll find_f(ll x){
return f[x]=(f[x]==x?x:find_f(f[x]));
}
void dfs(ll u,ll father){
f[u]=u;
vis[u]=1;
FORP(i,0,(ll)R[u].size()-1){
ll to=R[u][i];
if(to==father) continue;
else{
dist[to]=dist[u]+1;
dfs(to,u);
}
}
FORP(i,0,(ll)(que[u].size())-1){
ll to=que[u][i].first;
if(vis[to]){
ll p=find_f(to);
ans[que[u][i].second]=abs(dist[to]-dist[p])+abs(dist[u]-dist[p]);
}
}
f[u]=father;
}
int main() {
while (~scanf("%lld%lld",&n,&m)) {
init();
FORP(i,1,n){
FORP(j,1,m){
char s,t;
ll a,b;
cin>>s>>a>>t>>b;
ll u=getPos(i,j),v;
//其实知道边的建立过程可以不用管字母是啥
if(i<n){
v=getPos(i+1,j);
add(u,v,a);
}
if(j<m){
v=u+1;
add(u,v,b);
}
}
}
sort(E.begin(),E.end());
kruskal();
ll q;
cin>>q;
FORP(i,1,q){
ll x1,y1,x2,y2;
cin>>x1>>y1>>x2>>y2;
ll u=getPos(x1,y1);
ll v=getPos(x2,y2);
que[u].pb(mp(v,i));
que[v].pb(mp(u,i));
}
dfs(1,0);
FORP(i,1,q){
printf("%lld\n",ans[i]);
}
}
return 0;
}