题意:长度为n的序列a,其每个元素减去一个正数X得到序列b
n<=1e3,a[i]<=1e9.给出序列A(序列a,b打乱顺序).求出序列A中是否有满足的序列a和正数X存在.若存在输出解.
mn肯定为序列b元素,并且有个元素在序列a中和它对应(枚举该元素即差值)
则接下来未被标记中最小的肯定也为序列b元素,(若为序列a元素,则要存在一个比它小的能和它配对)
题意:n*m矩阵,只包含01.求出有多少个正方形子矩阵其边界都为1并且主对角线都为1.n,m<=2000.
核心:枚举全1主对角线贡献,即算出有多少个合法子矩形的主对角线在该条线上
预处理出每个1的二元组(r[i],l[i]) r[i]:向下和向右最多同时扩展长度.l[i]类似.
若对角线上(i,j)分别为左上和右下 则要满足i+r[i]-1>=j && i>=j-l[i]+1 && i<=j
处理对角线时,每处理一个元素 将其i+r[i]-1压入优先队列.
当枚举当前位置j为右下角时,用j淘汰掉队列若干个元素后,队列中剩下元素满足成为左上角的第一个条件
n<=1e3,a[i]<=1e9.给出序列A(序列a,b打乱顺序).求出序列A中是否有满足的序列a和正数X存在.若存在输出解.
mn肯定为序列b元素,并且有个元素在序列a中和它对应(枚举该元素即差值)
则接下来未被标记中最小的肯定也为序列b元素,(若为序列a元素,则要存在一个比它小的能和它配对)
根据差值 用map记录其对应元素.
#include <bits/stdc++.h>
using namespace std;
typedef pair<int,int> ii;
typedef long long ll;
const int N=2e3+20,inf=0x3f3f3f3f;
int n,a[N],vis[N];
map<int,int> mp;
vector<int> ans;
int main()
{
cin>>n;
n*=2;
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);//mp[a[i]]++;
sort(a+1,a+1+n);
int m=n/2;
for(int i=2;i<=n;i++)
{
int dif=a[i]-a[1],num=0;
mp.clear(),ans.clear();
for(int k=1;k<=n;k++)
{
if(mp[a[k]])
{
mp[a[k]]--;
ans.push_back(a[k]);
num++;
}
else
mp[a[k]+dif]++;
}
if(num==m)
{
printf("%d\n",dif);
for(int k=0;k<ans.size();k++)
printf("%d ",ans[k]);
printf("\n");
return 0;
}
}
puts("-1");
return 0;
}
题意:n*m矩阵,只包含01.求出有多少个正方形子矩阵其边界都为1并且主对角线都为1.n,m<=2000.
核心:枚举全1主对角线贡献,即算出有多少个合法子矩形的主对角线在该条线上
预处理出每个1的二元组(r[i],l[i]) r[i]:向下和向右最多同时扩展长度.l[i]类似.
若对角线上(i,j)分别为左上和右下 则要满足i+r[i]-1>=j && i>=j-l[i]+1 && i<=j
处理对角线时,每处理一个元素 将其i+r[i]-1压入优先队列.
当枚举当前位置j为右下角时,用j淘汰掉队列若干个元素后,队列中剩下元素满足成为左上角的第一个条件
用BIT记录队列中的元素i,则除了BIT前j-l[i]个不满足第二个条件外,其余都满足.复杂度O(n^2logn).
#include <bits/stdc++.h>
using namespace std;
typedef pair<int,int> ii;
typedef long long ll;
const int N=2e3+20,inf=0x3f3f3f3f;
char s[N][N];
int rig[N][N],lef[N][N],dow[N][N],up[N][N];
int row,col;
priority_queue<ii> q;
ll ans;
int c[N];
int lowbit(int x){return x&-x;}
void add(int x,int val)
{
int n=max(row,col);
for(int i=x;i<=n;i+=lowbit(i))
c[i]+=val;
}
int query(int x)
{
int res=0;
for(int i=x;i>=1;i-=lowbit(i))
res+=c[i];
return res;
}
void po()
{
int w=q.top().second;
add(w,-1);
q.pop();
}
void pus(int x,int y)
{
q.push(ii(-x,y));
add(y,1);
}
void solve(int i,int j)
{
for(int x=i,y=j;x<=row&&y<=col;x++,y++)
{
if(s[x][y]=='1')
{
while(!q.empty()&& -q.top().first<x)
po();
pus(x+min(rig[x][y],dow[x][y])-1,x);
ans+=q.size()-query(x-min(lef[x][y],up[x][y]));
}
else
while(!q.empty())
po();
}
while(!q.empty())
po();
}
int main()
{
cin>>row>>col;
for(int i=1;i<=row;i++)
scanf("%s",s[i]+1);
for(int i=1;i<=row;i++)
for(int j=1;j<=col;j++)
if(s[i][j]=='1')
lef[i][j]=lef[i][j-1]+1,up[i][j]=up[i-1][j]+1;
for(int i=row;i>=1;i--)
for(int j=col;j>=1;j--)
if(s[i][j]=='1')
rig[i][j]=rig[i][j+1]+1,dow[i][j]=dow[i+1][j]+1;
ans=0;
for(int i=1;i<=row;i++)
for(int j=1;j<=col;j++)
if(i==1||j==1)
solve(i,j);
cout<<ans<<endl;
return 0;
}