vj4补题
线段树+multiset(buhui)
原文链接:https://blog.csdn.net/m0_64158084/article/details/127790615
补充)set和mutiset
一个自动去重,一个不去重。
字典树/map
题目:给你一个N x N的矩阵,矩阵由小写字母和#组成,#为障碍。然后给出m个字符串和该字符串对应的值。然后从矩阵中截取子串,子串指矩阵中水平方向从左到右碰到障碍的最长串,或者竖直方向从上到下碰到障碍的最长串,也或是碰到矩阵边界的最长串,问这些子串是否都存在于m个给定的字符串中,若存在则输出值的总和,否则输出-1。
如果从矩阵中得到的单词在字典中不存在,那么输出 -1
!!!双等写成单等改了两个小时!!!
补充 unordered_map和map
unordered_map
不需要元素有序,只关心快速的插入、删除和查找操作,大多数查找操作都是常数时间复杂度的情况下。
map
元素的有序访问。
mp.count(s) 表示统计关联容器 mp 中键为 s 的元素出现的次数,返回次数。
遍历
map遍历
for(auto it=mp.begin();it!=mp.end();it++)
cout<<it->first<<" "<<it->second<<endl;
点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define Ios ios::sync_with_stdio(false),cin.tie(0)
#define mem(a,b) memset(a,b,sizeof a)
#define int long long
#define fi first
#define se second
#define endl '\n'
/**/
const int N = 2010, mod = 1e9+7;
int T, n, m;
char a[N][N];
unordered_map<string,int> mp, f;
signed main()
{
Ios;
cin >> T;
while(T--)
{
cin >> n >> m;
for(int i=1; i<=n; i++)
{
for(int j=1; j<=n; j++)
{
cin >> a[i][j];
}
}
mp.clear();
//记得清空
for(int i=1; i<=m; i++)
{
string s;
cin >> s;
int x;
cin>>x;
mp[s] = x;
}
int ans = 0, flag = 1;
//横着扫描
for(int i=1; i<=n; i++)
{
string s;
for(int j=1; j<=n; j++)
{
if(a[i][j] == '#')
{
if(s != "" && !mp.count(s)) flag = 0;
//矩阵中的单词不存在
else ans += mp[s];
s = "";
//置空s,重新统计
}
else s += a[i][j];
//string的拼接可用+
}
//到了边界
if(s != "" && !mp.count(s)) flag = 0;
else ans += mp[s];
}
//竖着扫描
for(int j=1; j<=n; j++)
{
string s;
for(int i=1; i<=n; i++)
{
if(a[i][j] == '#')
{
if(s != "" && !mp.count(s)) flag = 0;
else ans += mp[s];
s = "";
}
else s += a[i][j];
}
if(s != "" && !mp.count(s)) flag = 0;
else ans += mp[s];
}
if(!flag) cout << -1 << endl;
else cout << ans << endl;
}
return 0;
}
点击查看代码
#include<bits/stdc++.h>
using namespace std;
char a[1010][1010];
unordered_map<string,int> mp;
void solve()
{
int n,m;
cin>>n>>m;
for(int i=1; i<=n; i++)
{
for(int j=1; j<=n; j++)
{
cin>>a[i][j];
}
}
mp.clear();
while(m--)
{
string s;
int x;
cin>>s>>x;
mp[s]=x;
}
// for(auto it=mp.begin();it!=mp.end();it++)
// cout<<it->first<<" "<<it->second<<endl;
int ans=0;
int flag=1;
for(int i=1; i<=n; i++)
{
string s;
for(int j=1; j<=n; j++)
{
if(a[i][j]=='#')
{
if(s!=""&&!mp.count(s))
flag=0;
else
{
ans+=mp[s];
}
s="";
}
else
s+=a[i][j];
}
if(s!=""&&!mp.count(s))
flag=0;
else
ans+=mp[s];
}
for(int j=1; j<=n; j++)
{
string s;
for(int i=1; i<=n; i++)
{
if(a[i][j]=='#')
{
if(s!=""&&!mp.count(s))
flag=0;
else
{
ans+=mp[s];
}
s="";
}
else
s+=a[i][j];
}
if(s!=""&&!mp.count(s))
flag=0;
else
ans+=mp[s];
}
if(flag==0)
cout<<"-1"<<endl;
else
cout<<ans<<endl;
}
signed main()
{
int t;
cin>>t;
while(t--)
solve();
}
主席树模板题
https://blog.csdn.net/weixin_51797626/article/details/124561196
cf954 div3补题
思维
暴力超时,改变其实就是直接变成相邻格子的最大值即可。
简单贪心
动态规划+贪心
暴力:模拟可知,几种特殊情况,最重要的是相邻的数大于1,a+b一定小于a*b
题解
//一下的四道题没看。
数学+动态规划+贪心
构造回文序列?
https://www.luogu.com.cn/problem/solution/CF1986E
fg1g2
https://www.luogu.com.cn/problem/CF1986F
https://www.luogu.com.cn/problem/CF1986G1
https://www.luogu.com.cn/problem/CF1986G2
算法竞赛书(下午)
分治+排序
//nth_element()函数仅仅是将第n大的数排好了位置,并不返回值。
#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
int a[]={1,3,4,5,2,6,8,7,9};
int i;
cout<<"数列如下:"<<endl;
for(i=0;i<9;i++)
cout<<a[i]<<" ";
nth_element(a,a+5,a+9);
//排序第五个元素,记得都需要a+
//nth_element(array, array+6, array+len);
cout<<endl<<"输出第五大的数: "<<a[4]<<endl; //注意下标是从0开始计数的
return 0;
}
归并统计逆序对数量
点击查看代码
#include<cstdio>
#include<iostream>
using namespace std;
int n,a[500010],c[500010];
long long ans;
void msort(int b,int e)//归并排序
{
if(b==e)
return;
int mid=(b+e)/2,i=b,j=mid+1,k=b;
msort(b,mid),msort(mid+1,e);
while(i<=mid&&j<=e)
if(a[i]<=a[j])
c[k++]=a[i++];
else
c[k++]=a[j++],ans+=mid-i+1;//统计答案
while(i<=mid)
c[k++]=a[i++];
while(j<=e)
c[k++]=a[j++];
for(int l=b;l<=e;l++)
a[l]=c[l];
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
msort(1,n);
printf("%lld",ans);
return 0;
}
a^b的因子和
点击查看代码
#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll a,b,ans=1,mod=9901;
ll ksm(ll x,ll y){//快速幂
ll res=1;
while(y){
if(y%2==1)res=res*x%mod;
x=x*x%mod;
y/=2;
}
return res;
}
ll sum(ll x,ll y){//等比数列和
if(x==0)return 1;
if(x%2==1)return sum(x/2,y)*(1+ksm(y,x/2+1))%mod;
//偶数项,分两部分算(后半就是前半乘y^(x/2+1))
return (sum(x/2-1,y)*(1+ksm(y,x/2+1))+ksm(y,x/2))%mod;
//奇数项,加上中间一项
//因算了y^0,所以x%2==1是偶数项
}
int main (){
cin>>a>>b;
for(int i=2;i<=sqrt(a);i++){//质因数分解
int c=0;
while(a%i==0){
a/=i;
c++;
}
ans=ans*sum(c*b,i)%mod;
}
if(a!=1)
ans=ans*sum(b,a)%mod;
cout<<ans;
}